diff --git a/lib/galaxy/exceptions/__init__.py b/lib/galaxy/exceptions/__init__.py index 4d263dcdae4..390b1552935 100644 --- a/lib/galaxy/exceptions/__init__.py +++ b/lib/galaxy/exceptions/__init__.py @@ -60,6 +60,10 @@ class MalformedId( MessageException ): status_code = 400 err_code = error_codes.MALFORMED_ID +class UnknownContentsType( MessageException ): + status_code = 400 + err_code = error_codes.UNKNOWN_CONTENTS_TYPE + class RequestParameterMissingException( MessageException ): status_code = 400 err_code = error_codes.USER_REQUEST_MISSING_PARAMETER diff --git a/lib/galaxy/exceptions/error_codes.json b/lib/galaxy/exceptions/error_codes.json index 47cb208fa51..ec8c165ed3f 100644 --- a/lib/galaxy/exceptions/error_codes.json +++ b/lib/galaxy/exceptions/error_codes.json @@ -49,6 +49,11 @@ "code": 400009, "message": "The id of the resource is malformed." }, + { + "name": "UNKNOWN_CONTENTS_TYPE", + "code": 400010, + "message": "The request contains unknown type of contents." + }, { "name": "USER_NO_API_KEY", "code": 403001, diff --git a/lib/galaxy/model/tool_shed_install/__init__.py b/lib/galaxy/model/tool_shed_install/__init__.py index 5c6b034e9fa..d376f4d2e6f 100644 --- a/lib/galaxy/model/tool_shed_install/__init__.py +++ b/lib/galaxy/model/tool_shed_install/__init__.py @@ -4,6 +4,7 @@ from galaxy.model.item_attrs import Dictifiable from galaxy.util.bunch import Bunch from galaxy.util import asbool from tool_shed.util import common_util +from urlparse import urljoin log = logging.getLogger( __name__ ) @@ -73,6 +74,12 @@ class ToolShedRepository( object ): def can_reinstall_or_activate( self ): return self.deleted + def get_sharable_url( self, app ): + tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( app, self.tool_shed ) + if tool_shed_url: + return urljoin( tool_shed_url, 'view/%s/%s' % ( self.owner, self.name ) ) + return tool_shed_url + def get_shed_config_filename( self ): shed_config_filename = None if self.metadata: diff --git a/lib/galaxy/tools/errors.py b/lib/galaxy/tools/errors.py index 8410a7cfb4d..68e95be4187 100644 --- a/lib/galaxy/tools/errors.py +++ b/lib/galaxy/tools/errors.py @@ -28,7 +28,9 @@ ${message} ----------------------------------------------------------------------------- job id: ${job_id} tool id: ${job_tool_id} +tool version: ${tool_version} job pid or drm id: ${job_runner_external_id} +job tool version: ${job_tool_version} ----------------------------------------------------------------------------- job command line: ${job_command_line} @@ -86,7 +88,9 @@ class ErrorReporter( object ): history_item_name=hda.get_display_name(), history_view_link=history_view_link, job_id=job.id, + tool_version=job.tool_version, job_tool_id=job.tool_id, + job_tool_version=hda.tool_version, job_runner_external_id=job.job_runner_external_id, job_command_line=job.command_line, job_stderr=util.unicodify( job.stderr ), diff --git a/lib/galaxy/tools/parameters/basic.py b/lib/galaxy/tools/parameters/basic.py index 79a5151b5f0..126155ff1da 100644 --- a/lib/galaxy/tools/parameters/basic.py +++ b/lib/galaxy/tools/parameters/basic.py @@ -979,7 +979,7 @@ class SelectToolParameter( ToolParameter ): if option[2]: # Found selected option. value = option[1] - d[ 'value' ] = options + d[ 'value' ] = value return d diff --git a/lib/galaxy/util/biostar.py b/lib/galaxy/util/biostar.py index f7f4b3586e6..d5fea0e6501 100644 --- a/lib/galaxy/util/biostar.py +++ b/lib/galaxy/util/biostar.py @@ -86,7 +86,14 @@ def populate_tag_payload( payload=None, tool=None ): def populate_tool_payload( payload=None, tool=None ): payload = populate_tag_payload( payload=payload, tool=tool ) payload[ 'title' ] = 'Need help with "%s" tool' % ( tool.name ) - payload[ 'content' ] = '

Tool name: %s
Tool version: %s
Tool ID: %s

' % ( tool.name, tool.version, tool.id ) + tool_url = None + if tool.tool_shed_repository: + tool_url = tool.tool_shed_repository.get_sharable_url( tool.app ) + if tool_url: + tool_url = '
ToolShed URL: %s' % ( tool_url, tool_url ) + if not tool_url: + tool_url = '' + payload[ 'content' ] = '

Tool name: %s
Tool version: %s
Tool ID: %s%s


' % ( tool.name, tool.version, tool.id, tool_url ) return payload def determine_cookie_domain( galaxy_hostname, biostar_hostname ): diff --git a/lib/galaxy/webapps/galaxy/api/folder_contents.py b/lib/galaxy/webapps/galaxy/api/folder_contents.py index 0a2a5dea315..2ff777f418e 100644 --- a/lib/galaxy/webapps/galaxy/api/folder_contents.py +++ b/lib/galaxy/webapps/galaxy/api/folder_contents.py @@ -1,10 +1,15 @@ """ -API operations on the contents of a folder. +API operations on the contents of a library folder. """ -import logging from galaxy import web +from galaxy import exceptions +from galaxy.web import _future_expose_api as expose_api +from galaxy.web import _future_expose_api_anonymous as expose_api_anonymous +from sqlalchemy.orm.exc import MultipleResultsFound +from sqlalchemy.orm.exc import NoResultFound from galaxy.web.base.controller import BaseAPIController, UsesLibraryMixin, UsesLibraryMixinItems +import logging log = logging.getLogger( __name__ ) class FolderContentsController( BaseAPIController, UsesLibraryMixin, UsesLibraryMixinItems ): @@ -12,7 +17,111 @@ class FolderContentsController( BaseAPIController, UsesLibraryMixin, UsesLibrary Class controls retrieval, creation and updating of folder contents. """ - def load_folder_contents( self, trans, folder ): + @expose_api_anonymous + def index( self, trans, folder_id, **kwd ): + """ + GET /api/folders/{encoded_folder_id}/contents + Displays a collection (list) of a folder's contents (files and folders). + Encoded folder ID is prepended with 'F' if it is a folder as opposed to a data set which does not have it. + Full path is provided in response as a separate object providing data for breadcrumb path building. + """ + + if ( len( folder_id ) == 17 and folder_id.startswith( 'F' ) ): + try: + decoded_folder_id = trans.security.decode_id( folder_id[ 1: ] ) + except TypeError: + raise exceptions.MalformedId( 'Malformed folder id ( %s ) specified, unable to decode.' % str( folder_id ) ) + else: + raise exceptions.MalformedId( 'Malformed folder id ( %s ) specified, unable to decode.' % str( folder_id ) ) + + try: + folder = trans.sa_session.query( trans.app.model.LibraryFolder ).filter( trans.app.model.LibraryFolder.table.c.id == decoded_folder_id ).one() + except MultipleResultsFound: + raise exceptions.InconsistentDatabase( 'Multiple folders with same id found.' ) + except NoResultFound: + raise exceptions.ObjectNotFound( 'Folder with the id provided ( %s ) was not found' % str( folder_id ) ) + except Exception: + raise exceptions.InternalServerError( 'Error loading from the database.' ) + + current_user_roles = trans.get_current_user_roles() + can_add_library_item = trans.user_is_admin() or trans.app.security_agent.can_add_library_item( current_user_roles, folder ) + + if not ( trans.user_is_admin() or trans.app.security_agent.can_access_library_item( current_user_roles, folder, trans.user ) ): + if folder.parent_id == None: + try: + library = trans.sa_session.query( trans.app.model.Library ).filter( trans.app.model.Library.table.c.root_folder_id == decoded_folder_id ).one() + except Exception: + raise exceptions.InternalServerError( 'Error loading from the database.' ) + if trans.app.security_agent.library_is_public( library, contents=False ): + pass + else: + if trans.user: + log.warning( "SECURITY: User (id: %s) without proper access rights is trying to load folder with ID of %s" % ( trans.user.id, decoded_folder_id ) ) + else: + log.warning( "SECURITY: Anonymous user without proper access rights is trying to load folder with ID of %s" % ( decoded_folder_id ) ) + raise exceptions.ObjectNotFound( 'Folder with the id provided ( %s ) was not found' % str( folder_id ) ) + else: + if trans.user: + log.warning( "SECURITY: User (id: %s) without proper access rights is trying to load folder with ID of %s" % ( trans.user.id, decoded_folder_id ) ) + else: + log.warning( "SECURITY: Anonymous user without proper access rights is trying to load folder with ID of %s" % ( decoded_folder_id ) ) + raise exceptions.ObjectNotFound( 'Folder with the id provided ( %s ) was not found' % str( folder_id ) ) + + def build_path( folder ): + """ + Search the path upwards recursively and load the whole route of names and ids for breadcrumb building purposes. + """ + path_to_root = [] + # We are almost in root + if folder.parent_id is None: + path_to_root.append( ( 'F' + trans.security.encode_id( folder.id ), folder.name ) ) + else: + # We add the current folder and traverse up one folder. + path_to_root.append( ( 'F' + trans.security.encode_id( folder.id ), folder.name ) ) + upper_folder = trans.sa_session.query( trans.app.model.LibraryFolder ).get( folder.parent_id ) + path_to_root.extend( build_path( upper_folder ) ) + return path_to_root + + # Return the reversed path so it starts with the library node. + full_path = build_path( folder )[::-1] + + folder_contents = [] + time_updated = '' + time_created = '' + # Go through every accessible item in the folder and include its meta-data. + for content_item in self._load_folder_contents( trans, folder ): + if trans.app.security_agent.can_access_library_item( current_user_roles, content_item, trans.user ): + return_item = {} + encoded_id = trans.security.encode_id( content_item.id ) + time_updated = content_item.update_time.strftime( "%Y-%m-%d %I:%M %p" ) + time_created = content_item.create_time.strftime( "%Y-%m-%d %I:%M %p" ) + + # For folder return also hierarchy values + if content_item.api_type == 'folder': + encoded_id = 'F' + encoded_id + return_item.update ( dict ( item_count = content_item.item_count ) ) + + if content_item.api_type == 'file': + library_dataset_dict = content_item.to_dict() + library_dataset_dict['data_type'] + library_dataset_dict['file_size'] + library_dataset_dict['date_uploaded'] + return_item.update ( dict ( data_type = library_dataset_dict['data_type'], + file_size = library_dataset_dict['file_size'], + date_uploaded = library_dataset_dict['date_uploaded'] ) ) + + # For every item return also the default meta-data + return_item.update( dict( id = encoded_id, + type = content_item.api_type, + name = content_item.name, + time_updated = time_updated, + time_created = time_created + ) ) + folder_contents.append( return_item ) + + return { 'metadata' : { 'full_path' : full_path, 'can_add_library_item': can_add_library_item }, 'folder_contents' : folder_contents } + + def _load_folder_contents( self, trans, folder ): """ Loads all contents of the folder (folders and data sets) but only in the first level. """ @@ -33,101 +142,12 @@ class FolderContentsController( BaseAPIController, UsesLibraryMixin, UsesLibrary content_items.append( dataset ) return content_items - @web.expose_api - def index( self, trans, folder_id, **kwd ): - """ - GET /api/folders/{encoded_folder_id}/contents - Displays a collection (list) of a folder's contents (files and folders). - Encoded folder ID is prepended with 'F' if it is a folder as opposed to a data set which does not have it. - Full path is provided as a separate object in response providing data for breadcrumb path building. - """ - folder_container = [] - current_user_roles = trans.get_current_user_roles() - - if ( folder_id.startswith( 'F' ) ): - try: - decoded_folder_id = trans.security.decode_id( folder_id[1:] ) - except TypeError: - trans.response.status = 400 - return "Malformed folder id ( %s ) specified, unable to decode." % str( folder_id ) - - try: - folder = trans.sa_session.query( trans.app.model.LibraryFolder ).get( decoded_folder_id ) - except: - folder = None - log.error( "FolderContentsController.index: Unable to retrieve folder with ID: %s" % folder_id ) - - # We didn't find the folder or user does not have an access to it. - if not folder: - trans.response.status = 400 - return "Invalid folder id ( %s ) specified." % str( folder_id ) - - if not ( trans.user_is_admin() or trans.app.security_agent.can_access_library_item( current_user_roles, folder, trans.user ) ): - log.warning( "SECURITY: User (id: %s) without proper access rights is trying to load folder with ID of %s" % ( trans.user.id, folder.id ) ) - trans.response.status = 400 - return "Invalid folder id ( %s ) specified." % str( folder_id ) - - def build_path( folder ): - """ - Search the path upwards recursively and load the whole route of names and ids for breadcrumb purposes. - """ - path_to_root = [] - # We are almost in root - if folder.parent_id is None: - path_to_root.append( ( 'F' + trans.security.encode_id( folder.id ), folder.name ) ) - else: - # We add the current folder and traverse up one folder. - path_to_root.append( ( 'F' + trans.security.encode_id( folder.id ), folder.name ) ) - upper_folder = trans.sa_session.query( trans.app.model.LibraryFolder ).get( folder.parent_id ) - path_to_root.extend( build_path( upper_folder ) ) - return path_to_root - - # Return the reversed path so it starts with the library node. - full_path = build_path( folder )[::-1] - folder_container.append( dict( full_path = full_path ) ) - - folder_contents = [] - time_updated = '' - time_created = '' - # Go through every item in the folder and include its meta-data. - for content_item in self.load_folder_contents( trans, folder ): - return_item = {} - encoded_id = trans.security.encode_id( content_item.id ) - time_updated = content_item.update_time.strftime( "%Y-%m-%d %I:%M %p" ) - time_created = content_item.create_time.strftime( "%Y-%m-%d %I:%M %p" ) - - # For folder return also hierarchy values - if content_item.api_type == 'folder': - encoded_id = 'F' + encoded_id - return_item.update ( dict ( item_count = content_item.item_count ) ) - - if content_item.api_type == 'file': - library_dataset_dict = content_item.to_dict() - library_dataset_dict['data_type'] - library_dataset_dict['file_size'] - library_dataset_dict['date_uploaded'] - return_item.update ( dict ( data_type = library_dataset_dict['data_type'], - file_size = library_dataset_dict['file_size'], - date_uploaded = library_dataset_dict['date_uploaded'] ) ) - - # For every item return also the default meta-data - return_item.update( dict( id = encoded_id, - type = content_item.api_type, - name = content_item.name, - time_updated = time_updated, - time_created = time_created - ) ) - folder_contents.append( return_item ) - # Put the data in the container - folder_container.append( dict( folder_contents = folder_contents ) ) - return folder_container - @web.expose_api def show( self, trans, id, library_id, **kwd ): """ GET /api/folders/{encoded_folder_id}/ """ - pass + raise exceptions.NotImplemented( 'Showing the library folder content is not implemented.' ) @web.expose_api def create( self, trans, library_id, payload, **kwd ): @@ -136,11 +156,11 @@ class FolderContentsController( BaseAPIController, UsesLibraryMixin, UsesLibrary Creates a new folder. This should be superseded by the LibraryController. """ - pass + raise exceptions.NotImplemented( 'Creating the library folder content is not implemented.' ) @web.expose_api def update( self, trans, id, library_id, payload, **kwd ): """ PUT /api/folders/{encoded_folder_id}/contents """ - pass + raise exceptions.NotImplemented( 'Updating the library folder content is not implemented.' ) diff --git a/lib/galaxy/webapps/galaxy/api/folders.py b/lib/galaxy/webapps/galaxy/api/folders.py index 6c086334326..e9bec4529d9 100644 --- a/lib/galaxy/webapps/galaxy/api/folders.py +++ b/lib/galaxy/webapps/galaxy/api/folders.py @@ -1,14 +1,17 @@ """ -API operations on folders +API operations on library folders """ -import logging, os, string, shutil, urllib, re, socket, traceback +import os, string, shutil, urllib, re, socket, traceback from galaxy import datatypes, jobs, web, security +from galaxy.web import _future_expose_api as expose_api +from galaxy.web import _future_expose_api_anonymous as expose_api_anonymous from galaxy.web.base.controller import BaseAPIController,UsesLibraryMixin,UsesLibraryMixinItems from galaxy.util.sanitize_html import sanitize_html from cgi import escape, FieldStorage from paste.httpexceptions import HTTPBadRequest +import logging log = logging.getLogger( __name__ ) class FoldersController( BaseAPIController, UsesLibraryMixin, UsesLibraryMixinItems ): @@ -18,9 +21,9 @@ class FoldersController( BaseAPIController, UsesLibraryMixin, UsesLibraryMixinIt """ GET /api/folders/ This would normally display a list of folders. However, that would - be across multiple libraries, so it's not implemented yet. + be across multiple libraries, so it's not implemented. """ - pass + raise exceptions.NotImplemented( 'Listing all accessible library folders is not implemented.' ) @web.expose_api def show( self, trans, id, **kwd ): diff --git a/lib/galaxy/webapps/galaxy/api/history_contents.py b/lib/galaxy/webapps/galaxy/api/history_contents.py index a4c3c2c617a..66dfb0bceee 100644 --- a/lib/galaxy/webapps/galaxy/api/history_contents.py +++ b/lib/galaxy/webapps/galaxy/api/history_contents.py @@ -188,8 +188,7 @@ class HistoryContentsController( BaseAPIController, UsesHistoryDatasetAssociatio hda_dict[ 'display_apps' ] = self.get_display_apps( trans, hda ) return hda_dict - #TODO: allow anon users to copy hdas, ldas - @expose_api + @expose_api_anonymous def create( self, trans, history_id, payload, **kwd ): """ create( self, trans, history_id, payload, **kwd ) @@ -434,10 +433,7 @@ class HistoryContentsController( BaseAPIController, UsesHistoryDatasetAssociatio return validated_payload def __handle_unknown_contents_type( self, trans, contents_type ): - # TODO: raise a message exception instead of setting status and returning dict. - trans.response.status = 400 - return { 'error': 'Unknown contents type %s' % type } - + raise exceptions.UnknownContentsType('Unknown contents type: %s' % type) class HDAManager( object ): diff --git a/lib/galaxy/webapps/galaxy/api/lda_datasets.py b/lib/galaxy/webapps/galaxy/api/lda_datasets.py index 64f546397fb..50cecfcac2f 100644 --- a/lib/galaxy/webapps/galaxy/api/lda_datasets.py +++ b/lib/galaxy/webapps/galaxy/api/lda_datasets.py @@ -12,9 +12,13 @@ import tempfile import urllib import urllib2 import zipfile -from paste.httpexceptions import HTTPBadRequest -from galaxy import util, web -from galaxy.exceptions import ItemAccessibilityException, MessageException, ItemDeletionException, ObjectNotFound +from galaxy import exceptions +from galaxy.web import _future_expose_api as expose_api +from galaxy.web import _future_expose_api_anonymous as expose_api_anonymous +# from paste.httpexceptions import HTTPBadRequest +from galaxy import util +from galaxy import web +# from galaxy.exceptions import ItemAccessibilityException, MessageException, ItemDeletionException, ObjectNotFound from galaxy.security import Action from galaxy.util.streamball import StreamBall from galaxy.web.base.controller import BaseAPIController, UsesVisualizationMixin @@ -24,7 +28,7 @@ log = logging.getLogger( __name__ ) class LibraryDatasetsController( BaseAPIController, UsesVisualizationMixin ): - @web.expose_api + @expose_api_anonymous def show( self, trans, id, **kwd ): """ show( self, trans, id, **kwd ) @@ -41,19 +45,20 @@ class LibraryDatasetsController( BaseAPIController, UsesVisualizationMixin ): try: dataset = self.get_library_dataset( trans, id = id, check_ownership=False, check_accessible=True ) except Exception, e: - trans.response.status = 500 - return str( e ) - try: - rval = dataset.to_dict() - except Exception, e: - rval = "Error in dataset API at listing contents: " + str( e ) - log.error( rval + ": %s" % str(e), exc_info=True ) - trans.response.status = 500 - return "Error in dataset API at listing contents: " + str( e ) + raise exceptions.ObjectNotFound( 'Requested dataset was not found.' ) + # trans.response.status = 500 + # return str( e ) + # try: + rval = dataset.to_dict() + # except Exception, e: + # rval = "Error in dataset API at listing contents: " + str( e ) + # log.error( rval + ": %s" % str(e), exc_info=True ) + # trans.response.status = 500 + # return "Error in dataset API at listing contents: " + str( e ) rval['id'] = trans.security.encode_id(rval['id']); rval['ldda_id'] = trans.security.encode_id(rval['ldda_id']); - rval['folder_id'] = 'f' + trans.security.encode_id(rval['folder_id']) + rval['folder_id'] = 'F' + trans.security.encode_id(rval['folder_id']) return rval @web.expose diff --git a/lib/galaxy/webapps/galaxy/api/libraries.py b/lib/galaxy/webapps/galaxy/api/libraries.py index afd0da5397d..c29b5d11a82 100644 --- a/lib/galaxy/webapps/galaxy/api/libraries.py +++ b/lib/galaxy/webapps/galaxy/api/libraries.py @@ -7,7 +7,7 @@ from galaxy import exceptions from galaxy.web import _future_expose_api as expose_api from galaxy.web import _future_expose_api_anonymous as expose_api_anonymous from galaxy.model.orm import and_, not_, or_ -from galaxy.web.base.controller import BaseAPIController, url_for +from galaxy.web.base.controller import BaseAPIController import logging log = logging.getLogger( __name__ ) @@ -61,7 +61,6 @@ class LibrariesController( BaseAPIController ): if trans.app.security_agent.library_is_public( library, contents=False ): item[ 'public' ] = True current_user_roles = trans.get_current_user_roles() - # can_user_add = trans.app.security_agent.can_add_library_item( current_user_roles, library.root_folder ) if not trans.user_is_admin(): item['can_user_add'] = trans.app.security_agent.can_add_library_item( current_user_roles, library ) item['can_user_modify'] = trans.app.security_agent.can_modify_library_item( current_user_roles, library ) @@ -98,7 +97,7 @@ class LibrariesController( BaseAPIController ): deleted = util.string_as_bool( deleted ) try: decoded_library_id = trans.security.decode_id( library_id ) - except Exception: + except TypeError: raise exceptions.MalformedId( 'Malformed library id ( %s ) specified, unable to decode.' % id ) try: library = trans.sa_session.query( trans.app.model.Library ).get( decoded_library_id ) @@ -144,7 +143,14 @@ class LibrariesController( BaseAPIController ): library.root_folder = root_folder trans.sa_session.add_all( ( library, root_folder ) ) trans.sa_session.flush() - return library.to_dict( view='element', value_mapper={ 'id' : trans.security.encode_id , 'root_folder_id' : trans.security.encode_id } ) + + item = library.to_dict( view='element', value_mapper={ 'id' : trans.security.encode_id , 'root_folder_id' : trans.security.encode_id } ) + item['can_user_add'] = True + item['can_user_modify'] = True + item['can_user_manage'] = True + if trans.app.security_agent.library_is_public( library, contents=False ): + item[ 'public' ] = True + return item @expose_api def update( self, trans, id, **kwd ): diff --git a/lib/galaxy/webapps/galaxy/api/library_contents.py b/lib/galaxy/webapps/galaxy/api/library_contents.py index 192d9970853..ed1c8780534 100644 --- a/lib/galaxy/webapps/galaxy/api/library_contents.py +++ b/lib/galaxy/webapps/galaxy/api/library_contents.py @@ -17,8 +17,7 @@ import logging log = logging.getLogger( __name__ ) -class LibraryContentsController( BaseAPIController, UsesLibraryMixin, UsesLibraryMixinItems, - UsesHistoryDatasetAssociationMixin ): +class LibraryContentsController( BaseAPIController, UsesLibraryMixin, UsesLibraryMixinItems, UsesHistoryDatasetAssociationMixin ): @expose_api def index( self, trans, library_id, **kwd ): diff --git a/lib/galaxy/webapps/galaxy/buildapp.py b/lib/galaxy/webapps/galaxy/buildapp.py index 0f03469fe00..14bdfb7d9f7 100644 --- a/lib/galaxy/webapps/galaxy/buildapp.py +++ b/lib/galaxy/webapps/galaxy/buildapp.py @@ -284,7 +284,7 @@ def app_factory( global_conf, **kwargs ): # ==================== # Handle displaying tool help images and README file images contained in repositories installed from the tool shed. - webapp.add_route( '/admin_toolshed/static/images/:repository_id/:image_file', + webapp.add_route( '/admin_toolshed/static/images/:repository_id/{image_file:.+?}', controller='admin_toolshed', action='display_image_in_repository', repository_id=None, diff --git a/lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py b/lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py index 91d5f424a92..2caf1e23976 100644 --- a/lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py +++ b/lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py @@ -16,6 +16,7 @@ from tool_shed.util import common_install_util from tool_shed.util import data_manager_util from tool_shed.util import datatype_util from tool_shed.util import encoding_util +from tool_shed.util import hg_util from tool_shed.util import metadata_util from tool_shed.util import readme_util from tool_shed.util import repository_dependency_util @@ -1851,7 +1852,7 @@ class AdminToolshed( AdminGalaxy ): repo_files_dir = os.path.abspath( os.path.join( tool_path, relative_install_dir, name ) ) else: repo_files_dir = os.path.abspath( os.path.join( relative_install_dir, name ) ) - repo = hg.repository( suc.get_configured_ui(), path=repo_files_dir ) + repo = hg.repository( hg_util.get_configured_ui(), path=repo_files_dir ) repository_clone_url = os.path.join( tool_shed_url, 'repos', owner, name ) repository_util.pull_repository( repo, repository_clone_url, latest_ctx_rev ) suc.update_repository( repo, latest_ctx_rev ) diff --git a/lib/galaxy/webapps/tool_shed/api/repositories.py b/lib/galaxy/webapps/tool_shed/api/repositories.py index 3c5d839bad0..85064ee2701 100644 --- a/lib/galaxy/webapps/tool_shed/api/repositories.py +++ b/lib/galaxy/webapps/tool_shed/api/repositories.py @@ -13,6 +13,7 @@ import tool_shed.repository_types.util as rt_util import tool_shed.util.shed_util_common as suc from tool_shed.galaxy_install import repository_util from tool_shed.util import encoding_util +from tool_shed.util import hg_util from tool_shed.util import import_util from tool_shed.util import metadata_util from tool_shed.util import repository_maintenance_util @@ -49,7 +50,7 @@ class RepositoriesController( BaseAPIController ): log.debug( error_message ) return [] repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) ordered_installable_revisions = suc.get_ordered_metadata_changeset_revisions( repository, repo, downloadable=True ) return ordered_installable_revisions else: @@ -133,7 +134,7 @@ class RepositoriesController( BaseAPIController ): # The changeset_revision column in the repository_metadata table has been updated with a new # value value, so find the changeset_revision to which we need to update. repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) new_changeset_revision = suc.get_next_downloadable_changeset_revision( repository, repo, changeset_revision ) repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, encoded_repository_id, diff --git a/lib/galaxy/webapps/tool_shed/api/repository_revisions.py b/lib/galaxy/webapps/tool_shed/api/repository_revisions.py index 3fecaf2c085..1e807e89df4 100644 --- a/lib/galaxy/webapps/tool_shed/api/repository_revisions.py +++ b/lib/galaxy/webapps/tool_shed/api/repository_revisions.py @@ -6,6 +6,7 @@ from galaxy import util from galaxy.model.orm import and_, not_, select from galaxy.web.base.controller import BaseAPIController, HTTPBadRequest from tool_shed.util import export_util +from tool_shed.util import hg_util import tool_shed.util.shed_util_common as suc from galaxy import eggs @@ -168,7 +169,7 @@ class RepositoryRevisionsController( BaseAPIController ): # The changeset_revision column in the repository_metadata table has been updated with a new # value value, so find the changeset_revision to which we need to update. repo_dir = repository_dependency.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) new_changeset_revision = suc.get_next_downloadable_changeset_revision( repository_dependency, repo, changeset_revision ) diff --git a/lib/galaxy/webapps/tool_shed/controllers/repository.py b/lib/galaxy/webapps/tool_shed/controllers/repository.py index 39179c2a796..81340d131e0 100644 --- a/lib/galaxy/webapps/tool_shed/controllers/repository.py +++ b/lib/galaxy/webapps/tool_shed/controllers/repository.py @@ -19,6 +19,7 @@ from tool_shed.util import common_util from tool_shed.util import container_util from tool_shed.util import encoding_util from tool_shed.util import export_util +from tool_shed.util import hg_util from tool_shed.util import import_util from tool_shed.util import metadata_util from tool_shed.util import readme_util @@ -719,7 +720,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): status = kwd.get( 'status', 'done' ) commit_message = kwd.get( 'commit_message', 'Deleted selected files' ) repository = suc.get_repository_in_tool_shed( trans, id ) - repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) ) + repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) ) # Update repository files for browsing. suc.update_repository( repo ) changeset_revision = repository.tip( trans.app ) @@ -891,9 +892,9 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): changeset_revision = kwd.get( 'changeset_revision', None ) repository = suc.get_repository_by_name_and_owner( trans.app, name, owner ) repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) # Default to the current changeset revision. - update_to_ctx = suc.get_changectx_for_changeset( repo, changeset_revision ) + update_to_ctx = hg_util.get_changectx_for_changeset( repo, changeset_revision ) latest_changeset_revision = changeset_revision from_update_manager = kwd.get( 'from_update_manager', False ) if from_update_manager: @@ -937,10 +938,10 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): update_to_changeset_hash = None for changeset in repo.changelog: changeset_hash = str( repo.changectx( changeset ) ) - ctx = suc.get_changectx_for_changeset( repo, changeset_hash ) + ctx = hg_util.get_changectx_for_changeset( repo, changeset_hash ) if update_to_changeset_hash: if changeset_hash == repository.tip( trans.app ): - update_to_ctx = suc.get_changectx_for_changeset( repo, changeset_hash ) + update_to_ctx = hg_util.get_changectx_for_changeset( repo, changeset_hash ) latest_changeset_revision = changeset_hash break else: @@ -949,7 +950,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): changeset_hash ) if repository_metadata: # We found a RepositoryMetadata record. - update_to_ctx = suc.get_changectx_for_changeset( repo, changeset_hash ) + update_to_ctx = hg_util.get_changectx_for_changeset( repo, changeset_hash ) latest_changeset_revision = changeset_hash break else: @@ -1213,7 +1214,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): else: containers_dict = None export_repository_dependencies_check_box = None - revision_label = suc.get_revision_label( trans, repository, changeset_revision, include_date=True ) + revision_label = hg_util.get_revision_label( trans, repository, changeset_revision, include_date=True ) return trans.fill_template( "/webapps/tool_shed/repository/export_repository.mako", changeset_revision=changeset_revision, containers_dict=containers_dict, @@ -1466,9 +1467,9 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): has_repository_dependencies_only_if_compiling_contained_td = has_galaxy_utilities_dict[ 'has_repository_dependencies_only_if_compiling_contained_td' ] includes_workflows = has_galaxy_utilities_dict[ 'includes_workflows' ] repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) # Default to the received changeset revision and ctx_rev. - update_to_ctx = suc.get_changectx_for_changeset( repo, changeset_revision ) + update_to_ctx = hg_util.get_changectx_for_changeset( repo, changeset_revision ) ctx_rev = str( update_to_ctx.rev() ) latest_changeset_revision = changeset_revision update_dict = dict( changeset_revision=changeset_revision, @@ -1497,7 +1498,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): has_repository_dependencies = False has_repository_dependencies_only_if_compiling_contained_td = False changeset_hash = str( repo.changectx( changeset ) ) - ctx = suc.get_changectx_for_changeset( repo, changeset_hash ) + ctx = hg_util.get_changectx_for_changeset( repo, changeset_hash ) if update_to_changeset_hash: update_to_repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, trans.security.encode_id( repository.id ), @@ -1515,10 +1516,10 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): # We found a RepositoryMetadata record. if changeset_hash == repository.tip( trans.app ): # The current ctx is the repository tip, so use it. - update_to_ctx = suc.get_changectx_for_changeset( repo, changeset_hash ) + update_to_ctx = hg_util.get_changectx_for_changeset( repo, changeset_hash ) latest_changeset_revision = changeset_hash else: - update_to_ctx = suc.get_changectx_for_changeset( repo, update_to_changeset_hash ) + update_to_ctx = hg_util.get_changectx_for_changeset( repo, update_to_changeset_hash ) latest_changeset_revision = update_to_changeset_hash break elif not update_to_changeset_hash and changeset_hash == changeset_revision: @@ -1544,8 +1545,8 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): changeset_revision = kwd[ 'changeset_revision' ] repository = suc.get_repository_by_name_and_owner( trans.app, repository_name, repository_owner ) repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) - ctx = suc.get_changectx_for_changeset( repo, changeset_revision ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) + ctx = hg_util.get_changectx_for_changeset( repo, changeset_revision ) if ctx: return str( ctx.rev() ) return '' @@ -1560,8 +1561,8 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): def get_file_from_changeset_revision( self, repo_files_dir, changeset_revision, file_name, dir ): """Return file_name from the received changeset_revision of the repository manifest.""" stripped_file_name = suc.strip_path( file_name ) - repo = hg.repository( suc.get_configured_ui(), repo_files_dir ) - ctx = suc.get_changectx_for_changeset( repo, changeset_revision ) + repo = hg.repository( hg_util.get_configured_ui(), repo_files_dir ) + ctx = hg_util.get_changectx_for_changeset( repo, changeset_revision ) named_tmp_file = suc.get_named_tmpfile_from_ctx( ctx, file_name, dir ) return named_tmp_file @@ -1604,7 +1605,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): trans.model.Repository.table.c.user_id == user.id ) ): repository = repository_metadata.repository repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) latest_downloadable_changeset_revsion = suc.get_latest_downloadable_changeset_revision( trans, repository, repo ) if repository_metadata.changeset_revision == latest_downloadable_changeset_revsion: # We'll display only the test run for the latest installable revision in the rss feed. @@ -1672,7 +1673,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): if repository_name is not None and repository_owner is not None: repository = suc.get_repository_by_name_and_owner( trans.app, repository_name, repository_owner ) if repository: - repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) ) + repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) ) return suc.get_latest_downloadable_changeset_revision( trans, repository, repo ) return suc.INITIAL_CHANGELOG_HASH @@ -1855,7 +1856,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): changeset_revision = kwd[ 'changeset_revision' ] repository = suc.get_repository_by_name_and_owner( trans.app, name, owner ) repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) tool_version_dicts = [] for changeset in repo.changelog: current_changeset_revision = str( repo.changectx( changeset ) ) @@ -1880,7 +1881,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): repository_id = trans.security.encode_id( repository.id ) repository_clone_url = common_util.generate_clone_url_for_repository_in_tool_shed( trans, repository ) repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, repository_id, changeset_revision ) if not repository_metadata: # The received changeset_revision is no longer associated with metadata, so get the next changeset_revision in the repository @@ -1889,7 +1890,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): repo, after_changeset_revision=changeset_revision ) repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, repository_id, changeset_revision ) - ctx = suc.get_changectx_for_changeset( repo, changeset_revision ) + ctx = hg_util.get_changectx_for_changeset( repo, changeset_revision ) repo_info_dict = repository_util.create_repo_info_dict( trans=trans, repository_clone_url=repository_clone_url, changeset_revision=changeset_revision, @@ -2165,7 +2166,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): repository = suc.get_repository_in_tool_shed( trans, id ) repository_type = kwd.get( 'repository_type', str( repository.type ) ) repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) repo_name = kwd.get( 'repo_name', repository.name ) changeset_revision = kwd.get( 'changeset_revision', repository.tip( trans.app ) ) description = kwd.get( 'description', repository.description ) @@ -2317,7 +2318,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): selected_value=changeset_revision, add_id_to_name=False, downloadable=False ) - revision_label = suc.get_revision_label( trans, repository, repository.tip( trans.app ), include_date=False ) + revision_label = hg_util.get_revision_label( trans, repository, repository.tip( trans.app ), include_date=False ) repository_metadata = None metadata = None is_malicious = False @@ -2326,7 +2327,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): if changeset_revision != suc.INITIAL_CHANGELOG_HASH: repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, id, changeset_revision ) if repository_metadata: - revision_label = suc.get_revision_label( trans, repository, changeset_revision, include_date=False ) + revision_label = hg_util.get_revision_label( trans, repository, changeset_revision, include_date=False ) metadata = repository_metadata.metadata is_malicious = repository_metadata.malicious else: @@ -2337,7 +2338,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): if previous_changeset_revision != suc.INITIAL_CHANGELOG_HASH: repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, id, previous_changeset_revision ) if repository_metadata: - revision_label = suc.get_revision_label( trans, repository, previous_changeset_revision, include_date=False ) + revision_label = hg_util.get_revision_label( trans, repository, previous_changeset_revision, include_date=False ) metadata = repository_metadata.metadata is_malicious = repository_metadata.malicious changeset_revision = previous_changeset_revision @@ -2443,7 +2444,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): # There is no repository_metadata defined for the changeset_revision, so see if it was defined # in a previous changeset in the changelog. repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) previous_changeset_revision = \ suc.get_previous_metadata_changeset_revision( repository, repo, @@ -2520,7 +2521,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): changeset_revision = kwd.get( 'changeset_revision', None ) repository = suc.get_repository_by_name_and_owner( trans.app, name, owner ) repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) # Get the next installable changeset_revision beyond the received changeset_revision. changeset_revision = suc.get_next_downloadable_changeset_revision( repository, repo, changeset_revision ) if changeset_revision: @@ -2540,7 +2541,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): status = kwd.get( 'status', 'done' ) repository = suc.get_repository_in_tool_shed( trans, repository_id ) repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) changeset_revision = kwd.get( 'changeset_revision', repository.tip( trans.app ) ) repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, repository_id, changeset_revision ) if repository_metadata: @@ -2577,7 +2578,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): repository_metadata_id = None metadata = None repository_dependencies = None - revision_label = suc.get_revision_label( trans, repository, changeset_revision, include_date=True ) + revision_label = hg_util.get_revision_label( trans, repository, changeset_revision, include_date=True ) changeset_revision_select_field = grids_util.build_changeset_revision_select_field( trans, repository, selected_value=changeset_revision, @@ -2607,7 +2608,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): changeset_revision = kwd.get( 'changeset_revision', None ) repository = suc.get_repository_by_name_and_owner( trans.app, name, owner ) repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) # Get the lower bound changeset revision. lower_bound_changeset_revision = suc.get_previous_metadata_changeset_revision( repository, repo, changeset_revision, downloadable=True ) # Build the list of changeset revision hashes. @@ -2633,7 +2634,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): status='error' ) ) repository = suc.get_repository_in_tool_shed( trans, id ) changeset_revision = repository.tip( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) ) + repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) ) if repository.user == trans.user: return trans.response.send_redirect( web.url_for( controller='repository', action='browse_repositories', @@ -2651,7 +2652,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): changeset_revision, metadata_only=True ) repository_type_select_field = rt_util.build_repository_type_select_field( trans, repository=repository ) - revision_label = suc.get_revision_label( trans, repository, changeset_revision, include_date=True ) + revision_label = hg_util.get_revision_label( trans, repository, changeset_revision, include_date=True ) return trans.fill_template( '/webapps/tool_shed/repository/rate_repository.mako', repository=repository, metadata=metadata, @@ -2702,7 +2703,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): commit_message = kwd.get( 'commit_message', 'Deleted selected files' ) repository = suc.get_repository_in_tool_shed( trans, id ) repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) selected_files_to_delete = kwd.get( 'selected_files_to_delete', '' ) if kwd.get( 'select_files_to_delete_button', False ): if selected_files_to_delete: @@ -2742,7 +2743,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): # Update the repository files for browsing. suc.update_repository( repo ) # Get the new repository tip. - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) if tip == repository.tip( trans.app ): message += 'No changes to repository. ' kwd[ 'message' ] = message @@ -2931,7 +2932,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): if not repository_metadata: # Get updates to the received changeset_revision if any exist. repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) upper_bound_changeset_revision = suc.get_next_downloadable_changeset_revision( repository, repo, changeset_revision ) if upper_bound_changeset_revision: changeset_revision = upper_bound_changeset_revision @@ -2971,7 +2972,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): trans.security.encode_id( repository.id ), changeset_revision ) repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) tool_shed_status_dict = {} # Handle repository deprecation. tool_shed_status_dict[ 'repository_deprecated' ] = str( repository.deprecated ) @@ -3063,7 +3064,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): message = kwd.get( 'message', '' ) status = kwd.get( 'status', 'done' ) repository = suc.get_repository_in_tool_shed( trans, id ) - repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) ) + repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) ) changesets = [] for changeset in repo.changelog: ctx = repo.changectx( changeset ) @@ -3074,7 +3075,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): change_dict = { 'ctx' : ctx, 'rev' : str( ctx.rev() ), 'date' : date, - 'display_date' : suc.get_readable_ctx_date( ctx ), + 'display_date' : hg_util.get_readable_ctx_date( ctx ), 'description' : ctx.description(), 'files' : ctx.files(), 'user' : ctx.user(), @@ -3098,8 +3099,8 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): message = kwd.get( 'message', '' ) status = kwd.get( 'status', 'done' ) repository = suc.get_repository_in_tool_shed( trans, id ) - repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) ) - ctx = suc.get_changectx_for_changeset( repo, ctx_str ) + repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) ) + ctx = hg_util.get_changectx_for_changeset( repo, ctx_str ) if ctx is None: message = "Repository does not include changeset revision '%s'." % str( ctx_str ) status = 'error' @@ -3129,7 +3130,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): metadata = metadata_util.get_repository_metadata_by_repository_id_changeset_revision( trans, id, ctx_str, metadata_only=True ) # For rendering the prev button. if ctx_parent: - ctx_parent_date = suc.get_readable_ctx_date( ctx_parent ) + ctx_parent_date = hg_util.get_readable_ctx_date( ctx_parent ) ctx_parent_rev = ctx_parent.rev() if ctx_parent_rev < 0: prev = None @@ -3138,7 +3139,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): else: prev = None if ctx_child: - ctx_child_date = suc.get_readable_ctx_date( ctx_child ) + ctx_child_date = hg_util.get_readable_ctx_date( ctx_child ) ctx_child_rev = ctx_child.rev() next = "%s:%s (%s)" % ( ctx_child_rev, ctx_child, ctx_child_date ) else: @@ -3187,7 +3188,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): message = kwd.get( 'message', '' ) status = kwd.get( 'status', 'done' ) repository = suc.get_repository_in_tool_shed( trans, id ) - repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) ) + repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) ) avg_rating, num_ratings = self.get_ave_item_rating_data( trans.sa_session, repository, webapp_model=trans.model ) changeset_revision = kwd.get( 'changeset_revision', repository.tip( trans.app ) ) display_reviews = kwd.get( 'display_reviews', False ) @@ -3221,7 +3222,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): selected_value=changeset_revision, add_id_to_name=False, downloadable=False ) - revision_label = suc.get_revision_label( trans, repository, changeset_revision, include_date=False ) + revision_label = hg_util.get_revision_label( trans, repository, changeset_revision, include_date=False ) repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, id, changeset_revision ) if repository_metadata: metadata = repository_metadata.metadata @@ -3277,13 +3278,13 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ): render_repository_actions_for = kwd.get( 'render_repository_actions_for', 'tool_shed' ) repository = suc.get_repository_in_tool_shed( trans, repository_id ) repo_files_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_files_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_files_dir ) tool_metadata_dict = {} tool_lineage = [] tool = None guid = None original_tool_data_path = trans.app.config.tool_data_path - revision_label = suc.get_revision_label( trans, repository, changeset_revision, include_date=False ) + revision_label = hg_util.get_revision_label( trans, repository, changeset_revision, include_date=False ) repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, repository_id, changeset_revision ) if repository_metadata: repository_metadata_id = trans.security.encode_id( repository_metadata.id ) diff --git a/lib/galaxy/webapps/tool_shed/controllers/repository_review.py b/lib/galaxy/webapps/tool_shed/controllers/repository_review.py index 9015296c107..073dbf46891 100644 --- a/lib/galaxy/webapps/tool_shed/controllers/repository_review.py +++ b/lib/galaxy/webapps/tool_shed/controllers/repository_review.py @@ -7,6 +7,7 @@ from galaxy.model.orm import and_ from galaxy.webapps.tool_shed.util import ratings_util from tool_shed.util.container_util import STRSEP import tool_shed.util.shed_util_common as suc +from tool_shed.util import hg_util from tool_shed.util import review_util from galaxy.util.odict import odict import tool_shed.grids.repository_review_grids as repository_review_grids @@ -72,8 +73,8 @@ class RepositoryReviewController( BaseUIController, ratings_util.ItemRatings ): status = kwd.get( 'status', 'done' ) review = review_util.get_review( trans, kwd[ 'id' ] ) repository = review.repository - repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) ) - rev, changeset_revision_label = suc.get_rev_label_from_changeset_revision( repo, review.changeset_revision ) + repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) ) + rev, changeset_revision_label = hg_util.get_rev_label_from_changeset_revision( repo, review.changeset_revision ) return trans.fill_template( '/webapps/tool_shed/repository_review/browse_review.mako', repository=repository, changeset_revision_label=changeset_revision_label, @@ -232,7 +233,7 @@ class RepositoryReviewController( BaseUIController, ratings_util.ItemRatings ): for component in review_util.get_components( trans ): components_dict[ component.name ] = dict( component=component, component_review=None ) repository = review.repository - repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) ) + repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) ) for component_review in review.component_reviews: if component_review and component_review.component: component_name = component_review.component.name @@ -337,7 +338,7 @@ class RepositoryReviewController( BaseUIController, ratings_util.ItemRatings ): name='revision_approved', selected_value=selected_value, for_component=False ) - rev, changeset_revision_label = suc.get_rev_label_from_changeset_revision( repo, review.changeset_revision ) + rev, changeset_revision_label = hg_util.get_rev_label_from_changeset_revision( repo, review.changeset_revision ) return trans.fill_template( '/webapps/tool_shed/repository_review/edit_review.mako', repository=repository, review=review, @@ -470,7 +471,7 @@ class RepositoryReviewController( BaseUIController, ratings_util.ItemRatings ): if repository_id: repository = suc.get_repository_in_tool_shed( trans, repository_id ) repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) metadata_revision_hashes = [ metadata_revision.changeset_revision for metadata_revision in repository.metadata_revisions ] reviewed_revision_hashes = [ review.changeset_revision for review in repository.reviews ] reviews_dict = odict() @@ -478,7 +479,7 @@ class RepositoryReviewController( BaseUIController, ratings_util.ItemRatings ): ctx = repo.changectx( changeset ) changeset_revision = str( ctx ) if changeset_revision in metadata_revision_hashes or changeset_revision in reviewed_revision_hashes: - rev, changeset_revision_label = suc.get_rev_label_from_changeset_revision( repo, changeset_revision ) + rev, changeset_revision_label = hg_util.get_rev_label_from_changeset_revision( repo, changeset_revision ) if changeset_revision in reviewed_revision_hashes: # Find the review for this changeset_revision repository_reviews = review_util.get_reviews_by_repository_id_changeset_revision( trans, repository_id, changeset_revision ) @@ -517,9 +518,9 @@ class RepositoryReviewController( BaseUIController, ratings_util.ItemRatings ): changeset_revision = kwd.get( 'changeset_revision', None ) repository = suc.get_repository_in_tool_shed( trans, repository_id ) repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) installable = changeset_revision in [ metadata_revision.changeset_revision for metadata_revision in repository.metadata_revisions ] - rev, changeset_revision_label = suc.get_rev_label_from_changeset_revision( repo, changeset_revision ) + rev, changeset_revision_label = hg_util.get_rev_label_from_changeset_revision( repo, changeset_revision ) reviews = review_util.get_reviews_by_repository_id_changeset_revision( trans, repository_id, changeset_revision ) return trans.fill_template( '/webapps/tool_shed/repository_review/reviews_of_changeset_revision.mako', repository=repository, @@ -582,9 +583,9 @@ class RepositoryReviewController( BaseUIController, ratings_util.ItemRatings ): status = kwd.get( 'status', 'done' ) repository = suc.get_repository_in_tool_shed( trans, kwd[ 'id' ] ) changeset_revision = kwd.get( 'changeset_revision', None ) - repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) ) + repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) ) previous_reviews_dict = review_util.get_previous_repository_reviews( trans, repository, changeset_revision ) - rev, changeset_revision_label = suc.get_rev_label_from_changeset_revision( repo, changeset_revision ) + rev, changeset_revision_label = hg_util.get_rev_label_from_changeset_revision( repo, changeset_revision ) return trans.fill_template( '/webapps/tool_shed/repository_review/select_previous_review.mako', repository=repository, changeset_revision=changeset_revision, diff --git a/lib/galaxy/webapps/tool_shed/controllers/upload.py b/lib/galaxy/webapps/tool_shed/controllers/upload.py index d62ec65ec0e..1696d90536e 100644 --- a/lib/galaxy/webapps/tool_shed/controllers/upload.py +++ b/lib/galaxy/webapps/tool_shed/controllers/upload.py @@ -11,6 +11,7 @@ from galaxy.datatypes import checkers import tool_shed.repository_types.util as rt_util import tool_shed.util.shed_util_common as suc from tool_shed.util import commit_util +from tool_shed.util import hg_util from tool_shed.util import metadata_util from tool_shed.util import repository_dependency_util from tool_shed.util import tool_dependency_util @@ -39,7 +40,7 @@ class UploadController( BaseUIController ): repository_id = kwd.get( 'repository_id', '' ) repository = suc.get_repository_in_tool_shed( trans, repository_id ) repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) uncompress_file = util.string_as_bool( kwd.get( 'uncompress_file', 'true' ) ) remove_repo_files_not_in_tar = util.string_as_bool( kwd.get( 'remove_repo_files_not_in_tar', 'true' ) ) uploaded_file = None @@ -63,7 +64,7 @@ class UploadController( BaseUIController ): repo_url = 'http%s' % url[ len( 'hg' ): ] repo_url = repo_url.encode( 'ascii', 'replace' ) try: - commands.clone( suc.get_configured_ui(), repo_url, uploaded_directory ) + commands.clone( hg_util.get_configured_ui(), repo_url, uploaded_directory ) except Exception, e: message = 'Error uploading via mercurial clone: %s' % suc.to_html_string( str( e ) ) status = 'error' @@ -323,7 +324,7 @@ class UploadController( BaseUIController ): def upload_directory( self, trans, repository, uploaded_directory, upload_point, remove_repo_files_not_in_tar, commit_message, new_repo_alert ): repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) undesirable_dirs_removed = 0 undesirable_files_removed = 0 if upload_point is not None: @@ -387,7 +388,7 @@ class UploadController( BaseUIController ): def upload_tar( self, trans, repository, tar, uploaded_file, upload_point, remove_repo_files_not_in_tar, commit_message, new_repo_alert ): # Upload a tar archive of files. repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) undesirable_dirs_removed = 0 undesirable_files_removed = 0 ok, message = commit_util.check_archive( repository, tar ) diff --git a/lib/tool_shed/galaxy_install/repository_util.py b/lib/tool_shed/galaxy_install/repository_util.py index 63c4a02d7dd..29031531f86 100644 --- a/lib/tool_shed/galaxy_install/repository_util.py +++ b/lib/tool_shed/galaxy_install/repository_util.py @@ -15,6 +15,7 @@ from tool_shed.util import container_util from tool_shed.util import data_manager_util from tool_shed.util import datatype_util from tool_shed.util import encoding_util +from tool_shed.util import hg_util from tool_shed.util import repository_dependency_util from tool_shed.util import metadata_util from tool_shed.util import tool_dependency_util @@ -186,7 +187,7 @@ def get_repair_dict( trans, repository ): def get_repo_info_dict( trans, repository_id, changeset_revision ): repository = suc.get_repository_in_tool_shed( trans, repository_id ) repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) repository_clone_url = common_util.generate_clone_url_for_repository_in_tool_shed( trans, repository ) repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, repository_id, @@ -225,7 +226,7 @@ def get_repo_info_dict( trans, repository_id, changeset_revision ): has_repository_dependencies_only_if_compiling_contained_td = False includes_tool_dependencies = False includes_tools_for_display_in_tool_panel = False - ctx = suc.get_changectx_for_changeset( repo, changeset_revision ) + ctx = hg_util.get_changectx_for_changeset( repo, changeset_revision ) repo_info_dict = create_repo_info_dict( trans=trans, repository_clone_url=repository_clone_url, changeset_revision=changeset_revision, @@ -574,7 +575,7 @@ def install_tool_shed_repository( trans, tool_shed_repository, repo_info_dict, t current_changeset_revision = changeset_revision_dict.get( 'changeset_revision', None ) current_ctx_rev = changeset_revision_dict.get( 'ctx_rev', None ) if current_ctx_rev != ctx_rev: - repo = hg.repository( suc.get_configured_ui(), path=os.path.abspath( install_dir ) ) + repo = hg.repository( hg_util.get_configured_ui(), path=os.path.abspath( install_dir ) ) pull_repository( repo, repository_clone_url, current_changeset_revision ) suc.update_repository( repo, ctx_rev=current_ctx_rev ) handle_repository_contents( trans, @@ -804,7 +805,7 @@ def populate_containers_dict_for_new_install( trans, tool_shed_url, tool_path, r def pull_repository( repo, repository_clone_url, ctx_rev ): """Pull changes from a remote repository to a local one.""" - commands.pull( suc.get_configured_ui(), repo, source=repository_clone_url, rev=[ ctx_rev ] ) + commands.pull( hg_util.get_configured_ui(), repo, source=repository_clone_url, rev=[ ctx_rev ] ) def repair_tool_shed_repository( trans, repository, repo_info_dict ): diff --git a/lib/tool_shed/grids/admin_grids.py b/lib/tool_shed/grids/admin_grids.py index 9dab70e6fe6..d98e62fb0a5 100644 --- a/lib/tool_shed/grids/admin_grids.py +++ b/lib/tool_shed/grids/admin_grids.py @@ -5,6 +5,7 @@ from galaxy.web.framework.helpers import time_ago from galaxy.webapps.tool_shed import model from galaxy.model.orm import and_ import tool_shed.util.shed_util_common as suc +from tool_shed.util import hg_util from tool_shed.grids.repository_grids import CategoryGrid from tool_shed.grids.repository_grids import RepositoryGrid @@ -425,9 +426,11 @@ class RepositoryMetadataGrid( grids.Grid ): def get_value( self, trans, grid, repository_metadata ): repository = repository_metadata.repository - repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) ) - ctx = suc.get_changectx_for_changeset( repo, repository_metadata.changeset_revision ) - return suc.get_revision_label( trans, repository, repository_metadata.changeset_revision, include_date=True ) + return hg_util.get_revision_label( trans, + repository, + repository_metadata.changeset_revision, + include_date=True, + include_hash=True ) class ToolsColumn( grids.TextColumn ): diff --git a/lib/tool_shed/grids/repository_grids.py b/lib/tool_shed/grids/repository_grids.py index de2bac05d3e..36424f364bc 100644 --- a/lib/tool_shed/grids/repository_grids.py +++ b/lib/tool_shed/grids/repository_grids.py @@ -6,6 +6,7 @@ from galaxy.model.orm import and_ from galaxy.model.orm import or_ from galaxy.util import json from galaxy.util import listify +from tool_shed.util import hg_util import tool_shed.util.shed_util_common as suc import tool_shed.grids.util as grids_util import tool_shed.repository_types.util as rt_util @@ -116,7 +117,7 @@ class RepositoryGrid( grids.Grid ): def get_value( self, trans, grid, repository ): """Display the current repository heads.""" repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) heads = suc.get_repository_heads( repo ) multiple_heads = len( heads ) > 1 if multiple_heads: @@ -124,7 +125,7 @@ class RepositoryGrid( grids.Grid ): else: heads_str = '' for ctx in heads: - heads_str += '%s
' % suc.get_revision_label_from_ctx( ctx, include_date=True ) + heads_str += '%s
' % hg_util.get_revision_label_from_ctx( ctx, include_date=True ) heads_str.rstrip( '
' ) if multiple_heads: heads_str += '' @@ -1338,7 +1339,7 @@ class RepositoryMetadataGrid( grids.Grid ): def get_value( self, trans, grid, repository_metadata ): repository = repository_metadata.repository changeset_revision = repository_metadata.changeset_revision - changeset_revision_label = suc.get_revision_label( trans, repository, changeset_revision, include_date=True ) + changeset_revision_label = hg_util.get_revision_label( trans, repository, changeset_revision, include_date=True ) return changeset_revision_label @@ -1482,7 +1483,7 @@ class RepositoryDependenciesGrid( RepositoryMetadataGrid ): changeset_revision ) if not required_repository_metadata: repo_dir = required_repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) updated_changeset_revision = suc.get_next_downloadable_changeset_revision( required_repository, repo, changeset_revision ) required_repository_metadata = metadata_util.get_repository_metadata_by_repository_id_changeset_revision( trans, required_repository_id, @@ -2029,7 +2030,7 @@ def get_latest_downloadable_repository_metadata( trans, repository ): tool_dependency_definition. """ encoded_repository_id = trans.security.encode_id( repository.id ) - repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) ) + repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) ) tip_ctx = str( repo.changectx( repo.changelog.tip() ) ) repository_metadata = None try: @@ -2077,7 +2078,7 @@ def get_latest_repository_metadata( trans, repository ): tool_dependency_definition. """ encoded_repository_id = trans.security.encode_id( repository.id ) - repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) ) + repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) ) tip_ctx = str( repo.changectx( repo.changelog.tip() ) ) try: repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, encoded_repository_id, tip_ctx ) diff --git a/lib/tool_shed/grids/repository_review_grids.py b/lib/tool_shed/grids/repository_review_grids.py index ef04f27e535..fb0342f2383 100644 --- a/lib/tool_shed/grids/repository_review_grids.py +++ b/lib/tool_shed/grids/repository_review_grids.py @@ -6,6 +6,7 @@ from galaxy.model.orm import and_ from galaxy.model.orm import or_ from tool_shed.grids.repository_grids import RepositoryGrid import tool_shed.util.shed_util_common as suc +from tool_shed.util import hg_util from tool_shed.util import metadata_util from galaxy import eggs @@ -66,10 +67,10 @@ class RepositoriesWithReviewsGrid( RepositoryGrid ): # Restrict to revisions that have been reviewed. if repository.reviews: rval = '' - repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) ) + repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) ) for review in repository.reviews: changeset_revision = review.changeset_revision - rev, label = suc.get_rev_label_from_changeset_revision( repo, changeset_revision ) + rev, label = hg_util.get_rev_label_from_changeset_revision( repo, changeset_revision ) rval += '%s
' % \ ( trans.security.encode_id( repository.id ), changeset_revision, label ) return rval @@ -85,9 +86,11 @@ class RepositoriesWithReviewsGrid( RepositoryGrid ): rval = '' for repository_metadata in repository_metadata_revisions: rev, label, changeset_revision = \ - metadata_util.get_rev_label_changeset_revision_from_repository_metadata( trans, - repository_metadata, - repository=repository ) + hg_util.get_rev_label_changeset_revision_from_repository_metadata( trans, + repository_metadata, + repository=repository, + include_date=True, + include_hash=False ) rval += '%s
' % \ ( trans.security.encode_id( repository.id ), changeset_revision, label ) return rval @@ -308,7 +311,11 @@ class RepositoryReviewsByUserGrid( grids.Grid ): rval += 'edit_review' else: rval +='browse_review' - revision_label = suc.get_revision_label( trans, review.repository, review.changeset_revision, include_date=True ) + revision_label = hg_util.get_revision_label( trans, + review.repository, + review.changeset_revision, + include_date=True, + include_hash=False ) rval += '?id=%s">%s' % ( encoded_review_id, revision_label ) return rval diff --git a/lib/tool_shed/grids/util.py b/lib/tool_shed/grids/util.py index 9720b5227b1..72902087d1d 100644 --- a/lib/tool_shed/grids/util.py +++ b/lib/tool_shed/grids/util.py @@ -1,7 +1,7 @@ import logging import os import tool_shed.util.shed_util_common as suc -import tool_shed.util.metadata_util as metadata_util +from tool_shed.util import hg_util from galaxy.web.form_builder import SelectField from galaxy.util.bunch import Bunch @@ -96,9 +96,11 @@ def build_changeset_revision_select_field( trans, repository, selected_value=Non repository_metadata_revisions = repository.metadata_revisions for repository_metadata in repository_metadata_revisions: rev, label, changeset_revision = \ - metadata_util.get_rev_label_changeset_revision_from_repository_metadata( trans, - repository_metadata, - repository=repository ) + hg_util.get_rev_label_changeset_revision_from_repository_metadata( trans, + repository_metadata, + repository=repository, + include_date=True, + include_hash=False ) changeset_tups.append( ( rev, label, changeset_revision ) ) refresh_on_change_values.append( changeset_revision ) # Sort options by the revision label. Even though the downloadable_revisions query sorts by update_time, diff --git a/lib/tool_shed/scripts/check_repositories_for_functional_tests.py b/lib/tool_shed/scripts/check_repositories_for_functional_tests.py index f36f136f5f4..bb5ac6cb6ae 100644 --- a/lib/tool_shed/scripts/check_repositories_for_functional_tests.py +++ b/lib/tool_shed/scripts/check_repositories_for_functional_tests.py @@ -14,6 +14,7 @@ eggs.require( 'mercurial' ) import ConfigParser import galaxy.webapps.tool_shed.config as tool_shed_config +from tool_shed.util import hg_util import tool_shed.util.shed_util_common as suc import logging import shutil @@ -109,7 +110,7 @@ def check_and_update_repository_metadata( app, info_only=False, verbosity=1 ): if tool_dicts is not None: # Clone the repository up to the changeset revision we're checking. repo_dir = repository.repo_path( app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) work_dir = tempfile.mkdtemp( prefix="tmp-toolshed-cafr" ) cloned_ok, error_message = suc.clone_repository( repo_dir, work_dir, changeset_revision ) if cloned_ok: @@ -368,7 +369,7 @@ def should_set_do_not_test_flag( app, repository, changeset_revision, testable_r """ if not testable_revision: repo_dir = repository.repo_path( app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) changeset_revisions = suc.get_ordered_metadata_changeset_revisions( repository, repo, downloadable=True ) if len( changeset_revisions ) > 1: latest_downloadable_revision = changeset_revisions[ -1 ] diff --git a/lib/tool_shed/util/commit_util.py b/lib/tool_shed/util/commit_util.py index 7c5501ad535..a449cfbf089 100644 --- a/lib/tool_shed/util/commit_util.py +++ b/lib/tool_shed/util/commit_util.py @@ -12,6 +12,7 @@ from galaxy.util import json from galaxy.util.odict import odict from galaxy.web import url_for import tool_shed.util.shed_util_common as suc +from tool_shed.util import hg_util from tool_shed.util import tool_util from tool_shed.util import xml_util import tool_shed.repository_types.util as rt_util @@ -156,7 +157,7 @@ def handle_complex_repository_dependency_elem( trans, elem, sub_elem_index, sub_ def handle_directory_changes( trans, repository, full_path, filenames_in_archive, remove_repo_files_not_in_tar, new_repo_alert, commit_message, undesirable_dirs_removed, undesirable_files_removed ): repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) content_alert_str = '' files_to_remove = [] filenames_in_archive = [ os.path.join( full_path, name ) for name in filenames_in_archive ] @@ -342,7 +343,7 @@ def handle_repository_dependency_elem( trans, elem, unpopulate=False ): repository = suc.get_repository_by_name_and_owner( trans.app, name, owner ) if repository: repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) lastest_installable_changeset_revision = suc.get_latest_downloadable_changeset_revision( trans, repository, repo ) if lastest_installable_changeset_revision != suc.INITIAL_CHANGELOG_HASH: elem.attrib[ 'changeset_revision' ] = lastest_installable_changeset_revision diff --git a/lib/tool_shed/util/export_util.py b/lib/tool_shed/util/export_util.py index 347da0e6e40..c90ad687813 100644 --- a/lib/tool_shed/util/export_util.py +++ b/lib/tool_shed/util/export_util.py @@ -14,6 +14,7 @@ from tool_shed.util import commit_util from tool_shed.util import common_install_util from tool_shed.util import common_util from tool_shed.util import encoding_util +from tool_shed.util import hg_util from tool_shed.util import repository_dependency_util from tool_shed.util import xml_util @@ -37,7 +38,7 @@ class ExportedRepositoryRegistry( object ): def archive_repository_revision( trans, ui, repository, archive_dir, changeset_revision ): '''Create an un-versioned archive of a repository.''' - repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) ) + repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) ) options_dict = suc.get_mercurial_default_options_dict( 'archive' ) options_dict[ 'rev' ] = changeset_revision error_message = '' @@ -233,8 +234,8 @@ def get_repo_info_dicts( trans, tool_shed_url, repository_id, changeset_revision key_rd_dicts_to_be_processed=None, all_repository_dependencies=None, handled_key_rd_dicts=None ) - repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) ) - ctx = suc.get_changectx_for_changeset( repo, changeset_revision ) + repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) ) + ctx = hg_util.get_changectx_for_changeset( repo, changeset_revision ) repo_info_dict = {} # Cast unicode to string. repo_info_dict[ str( repository.name ) ] = ( str( repository.description ), diff --git a/lib/tool_shed/util/hg_util.py b/lib/tool_shed/util/hg_util.py new file mode 100644 index 00000000000..90094d8ae31 --- /dev/null +++ b/lib/tool_shed/util/hg_util.py @@ -0,0 +1,108 @@ +import logging +from datetime import datetime +from time import gmtime +from time import strftime + +from galaxy import eggs +eggs.require( 'mercurial' ) + +from mercurial import cmdutil +from mercurial import commands +from mercurial import hg +from mercurial import ui + +def get_changectx_for_changeset( repo, changeset_revision, **kwd ): + """Retrieve a specified changectx from a repository.""" + for changeset in repo.changelog: + ctx = repo.changectx( changeset ) + if str( ctx ) == changeset_revision: + return ctx + return None + +def get_configured_ui(): + """Configure any desired ui settings.""" + _ui = ui.ui() + # The following will suppress all messages. This is + # the same as adding the following setting to the repo + # hgrc file' [ui] section: + # quiet = True + _ui.setconfig( 'ui', 'quiet', True ) + return _ui + +def get_readable_ctx_date( ctx ): + """Convert the date of the changeset (the received ctx) to a human-readable date.""" + t, tz = ctx.date() + date = datetime( *gmtime( float( t ) - tz )[ :6 ] ) + ctx_date = date.strftime( "%Y-%m-%d" ) + return ctx_date + +def get_revision_label( trans, repository, changeset_revision, include_date=True, include_hash=True ): + """ + Return a string consisting of the human read-able changeset rev and the changeset revision string + which includes the revision date if the receive include_date is True. + """ + repo = hg.repository( get_configured_ui(), repository.repo_path( trans.app ) ) + ctx = get_changectx_for_changeset( repo, changeset_revision ) + if ctx: + return get_revision_label_from_ctx( ctx, include_date=include_date, include_hash=include_hash ) + else: + if include_hash: + return "-1:%s" % changeset_revision + else: + return "-1" + +def get_rev_label_changeset_revision_from_repository_metadata( trans, repository_metadata, repository=None, + include_date=True, include_hash=True ): + if repository is None: + repository = repository_metadata.repository + repo = hg.repository( get_configured_ui(), repository.repo_path( trans.app ) ) + changeset_revision = repository_metadata.changeset_revision + ctx = get_changectx_for_changeset( repo, changeset_revision ) + if ctx: + rev = '%04d' % ctx.rev() + if include_date: + changeset_revision_date = get_readable_ctx_date( ctx ) + if include_hash: + label = "%s:%s (%s)" % ( str( ctx.rev() ), changeset_revision, changeset_revision_date ) + else: + label = "%s (%s)" % ( str( ctx.rev() ), changeset_revision_date ) + else: + if include_hash: + label = "%s:%s" % ( str( ctx.rev() ), changeset_revision ) + else: + label = "%s" % str( ctx.rev() ) + else: + rev = '-1' + if include_hash: + label = "-1:%s" % changeset_revision + else: + label = "-1" + return rev, label, changeset_revision + +def get_revision_label_from_ctx( ctx, include_date=True, include_hash=True ): + if include_date: + if include_hash: + return '%s:%s (%s)' % \ + ( str( ctx.rev() ), str( ctx ), str( get_readable_ctx_date( ctx ) ) ) + else: + return '%s (%s)' % \ + ( str( ctx.rev() ), str( get_readable_ctx_date( ctx ) ) ) + else: + if include_hash: + return '%s:%s' % ( str( ctx.rev() ), str( ctx ) ) + else: + return '%s' % str( ctx.rev() ) + +def get_rev_label_from_changeset_revision( repo, changeset_revision, include_date=True, include_hash=True ): + """ + Given a changeset revision hash, return two strings, the changeset rev and the changeset revision hash + which includes the revision date if the receive include_date is True. + """ + ctx = get_changectx_for_changeset( repo, changeset_revision ) + if ctx: + rev = '%04d' % ctx.rev() + label = get_revision_label_from_ctx( ctx, include_date=include_date ) + else: + rev = '-1' + label = "-1:%s" % changeset_revision + return rev, label diff --git a/lib/tool_shed/util/import_util.py b/lib/tool_shed/util/import_util.py index 919e07305a5..39d066b2a2d 100644 --- a/lib/tool_shed/util/import_util.py +++ b/lib/tool_shed/util/import_util.py @@ -8,6 +8,7 @@ from galaxy import util from galaxy.datatypes import checkers from tool_shed.util import commit_util from tool_shed.util import encoding_util +from tool_shed.util import hg_util from tool_shed.util import metadata_util from tool_shed.util import xml_util import tool_shed.util.shed_util_common as suc @@ -212,7 +213,7 @@ def import_repository_archive( trans, repository, repository_archive_dict ): archive_file_path = os.path.join( file_path, archive_file_name ) archive = tarfile.open( archive_file_path, 'r:*' ) repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) undesirable_dirs_removed = 0 undesirable_files_removed = 0 ok, error_message = commit_util.check_archive( repository, archive ) diff --git a/lib/tool_shed/util/metadata_util.py b/lib/tool_shed/util/metadata_util.py index 799bab2a4f7..7fa90272a0f 100644 --- a/lib/tool_shed/util/metadata_util.py +++ b/lib/tool_shed/util/metadata_util.py @@ -15,6 +15,7 @@ from tool_shed.repository_types.metadata import TipOnly from tool_shed.util import common_util from tool_shed.util import common_install_util from tool_shed.util import container_util +from tool_shed.util import hg_util from tool_shed.util import readme_util from tool_shed.util import tool_dependency_util from tool_shed.util import tool_util @@ -347,7 +348,7 @@ def create_or_update_repository_metadata( trans, id, repository, changeset_revis # changeset revision in the received repository's changelog (up to the received changeset revision) to see if it is contained in the # skip_tool_test table. If it is, but is not associated with a repository_metadata record, reset that skip_tool_test record to the # newly created repository_metadata record. - repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) ) + repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) ) for changeset in repo.changelog: changeset_hash = str( repo.changectx( changeset ) ) skip_tool_test = suc.get_skip_tool_test_by_changeset_revision( trans, changeset_hash ) @@ -1048,7 +1049,7 @@ def generate_workflow_metadata( relative_path, exported_workflow_dict, metadata_ def get_latest_repository_metadata( trans, decoded_repository_id, downloadable=False ): """Get last metadata defined for a specified repository from the database.""" repository = trans.sa_session.query( trans.model.Repository ).get( decoded_repository_id ) - repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) ) + repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) ) if downloadable: changeset_revision = suc.get_latest_downloadable_changeset_revision( trans, repository, repo ) else: @@ -1121,21 +1122,6 @@ def get_repository_metadata_revisions_for_review( repository, reviewed=True ): repository_metadata_revisions.append( metadata_revision ) return repository_metadata_revisions -def get_rev_label_changeset_revision_from_repository_metadata( trans, repository_metadata, repository=None ): - if repository is None: - repository = repository_metadata.repository - repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) ) - changeset_revision = repository_metadata.changeset_revision - ctx = suc.get_changectx_for_changeset( repo, changeset_revision ) - if ctx: - changeset_revision_date = suc.get_readable_ctx_date( ctx ) - rev = '%04d' % ctx.rev() - label = "%s:%s (%s)" % ( str( ctx.rev() ), changeset_revision, changeset_revision_date ) - else: - rev = '-1' - label = "-1:%s" % changeset_revision - return rev, label, changeset_revision - def get_sample_files_from_disk( repository_files_dir, tool_path=None, relative_install_dir=None, resetting_all_metadata_on_repository=False ): if resetting_all_metadata_on_repository: @@ -1294,7 +1280,7 @@ def handle_repository_elem( app, repository_elem, only_if_compiling_contained_td log.debug( error_message ) is_valid = False return repository_dependency_tup, is_valid, error_message - repo = hg.repository( suc.get_configured_ui(), repository.repo_path( app ) ) + repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( app ) ) # The received changeset_revision may be None since defining it in the dependency definition is optional. # If this is the case, the default will be to set it's value to the repository dependency tip revision. # This probably occurs only when handling circular dependency definitions. @@ -1360,7 +1346,7 @@ def is_level_one_certified( trans, repository ): """ if repository.deleted: return ( None, False ) - repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) ) + repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) ) # Get the latest installable changeset revision since that is all that is currently configured for testing. latest_installable_changeset_revision = suc.get_latest_downloadable_changeset_revision( trans, repository, repo ) if latest_installable_changeset_revision not in [ None, suc.INITIAL_CHANGELOG_HASH ]: @@ -1797,7 +1783,7 @@ def reset_all_metadata_on_repository_in_tool_shed( trans, id ): repository = suc.get_repository_in_tool_shed( trans, id ) log.debug( "Resetting all metadata on repository: %s" % repository.name ) repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) repository_clone_url = common_util.generate_clone_url_for_repository_in_tool_shed( trans, repository ) # The list of changeset_revisions refers to repository_metadata records that have been created or updated. When the following loop # completes, we'll delete all repository_metadata records for this repository that do not have a changeset_revision value in this list. @@ -1978,7 +1964,7 @@ def set_repository_metadata( trans, repository, content_alert_str='', **kwd ): encoded_id = trans.security.encode_id( repository.id ) repository_clone_url = common_util.generate_clone_url_for_repository_in_tool_shed( trans, repository ) repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) metadata_dict, invalid_file_tups = generate_metadata_for_changeset_revision( app=trans.app, repository=repository, changeset_revision=repository.tip( trans.app ), diff --git a/lib/tool_shed/util/readme_util.py b/lib/tool_shed/util/readme_util.py index a7e82d8a77b..41778d96b72 100644 --- a/lib/tool_shed/util/readme_util.py +++ b/lib/tool_shed/util/readme_util.py @@ -9,6 +9,7 @@ from galaxy.util import rst_to_html from galaxy.util import unicodify import tool_shed.util.shed_util_common as suc from tool_shed.util import common_util +from tool_shed.util import hg_util eggs.require( 'mercurial' ) @@ -25,7 +26,7 @@ def build_readme_files_dict( trans, repository, changeset_revision, metadata, to if trans.webapp.name == 'galaxy': can_use_disk_files = True else: - repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) ) + repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) ) latest_downloadable_changeset_revision = suc.get_latest_downloadable_changeset_revision( trans, repository, repo ) can_use_disk_files = changeset_revision == latest_downloadable_changeset_revision readme_files_dict = {} @@ -74,7 +75,7 @@ def build_readme_files_dict( trans, repository, changeset_revision, metadata, to readme_files_dict[ readme_file_name ] = text_of_reasonable_length else: # We must be in the tool shed and have an old changeset_revision, so we need to retrieve the file contents from the repository manifest. - ctx = suc.get_changectx_for_changeset( repo, changeset_revision ) + ctx = hg_util.get_changectx_for_changeset( repo, changeset_revision ) if ctx: fctx = suc.get_file_context_from_ctx( ctx, readme_file_name ) if fctx and fctx not in [ 'DELETED' ]: diff --git a/lib/tool_shed/util/repository_dependency_util.py b/lib/tool_shed/util/repository_dependency_util.py index b74e73f4be6..05a54fd87e0 100644 --- a/lib/tool_shed/util/repository_dependency_util.py +++ b/lib/tool_shed/util/repository_dependency_util.py @@ -9,6 +9,7 @@ from tool_shed.util import common_util from tool_shed.util import common_install_util from tool_shed.util import container_util from tool_shed.util import encoding_util +from tool_shed.util import hg_util from tool_shed.util import metadata_util from tool_shed.util import tool_util @@ -532,7 +533,7 @@ def get_updated_changeset_revisions_for_repository_dependencies( trans, key_rd_d else: # The repository changeset_revision is no longer installable, so see if there's been an update. repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) changeset_revision = suc.get_next_downloadable_changeset_revision( repository, repo, rd_changeset_revision ) repository_metadata = metadata_util.get_repository_metadata_by_repository_id_changeset_revision( trans, trans.security.encode_id( repository.id ), diff --git a/lib/tool_shed/util/repository_maintenance_util.py b/lib/tool_shed/util/repository_maintenance_util.py index d8910586871..67a23da28c3 100644 --- a/lib/tool_shed/util/repository_maintenance_util.py +++ b/lib/tool_shed/util/repository_maintenance_util.py @@ -3,6 +3,7 @@ import logging import os import re import tool_shed.util.shed_util_common as suc +from tool_shed.util import hg_util from tool_shed.util import import_util from galaxy import util from galaxy.web.form_builder import build_select_field @@ -47,7 +48,7 @@ def create_hgrc_file( trans, repository ): # Since we support both http and https, we set push_ssl to False to override the default (which is True) in the mercurial api. The hg # purge extension purges all files and directories not being tracked by mercurial in the current repository. It'll remove unknown files # and empty directories. This is not currently used because it is not supported in the mercurial API. - repo = hg.repository( suc.get_configured_ui(), path=repository.repo_path( trans.app ) ) + repo = hg.repository( hg_util.get_configured_ui(), path=repository.repo_path( trans.app ) ) fp = repo.opener( 'hgrc', 'wb' ) fp.write( '[paths]\n' ) fp.write( 'default = .\n' ) @@ -83,7 +84,7 @@ def create_repository( trans, name, type, description, long_description, user_id if not os.path.exists( repository_path ): os.makedirs( repository_path ) # Create the local repository. - repo = hg.repository( suc.get_configured_ui(), repository_path, create=True ) + repo = hg.repository( hg_util.get_configured_ui(), repository_path, create=True ) # Add an entry in the hgweb.config file for the local repository. lhs = "repos/%s/%s" % ( repository.user.username, repository.name ) trans.app.hgweb_config_manager.add_entry( lhs, repository_path ) diff --git a/lib/tool_shed/util/review_util.py b/lib/tool_shed/util/review_util.py index e84c50d9867..9539d52d808 100644 --- a/lib/tool_shed/util/review_util.py +++ b/lib/tool_shed/util/review_util.py @@ -3,6 +3,7 @@ import os from galaxy import eggs from galaxy.model.orm import and_ from galaxy.util.odict import odict +from tool_shed.util import hg_util import tool_shed.util.shed_util_common as suc eggs.require( 'mercurial' ) @@ -58,13 +59,13 @@ def get_components( trans ): def get_previous_repository_reviews( trans, repository, changeset_revision ): """Return an ordered dictionary of repository reviews up to and including the received changeset revision.""" - repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) ) + repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) ) reviewed_revision_hashes = [ review.changeset_revision for review in repository.reviews ] previous_reviews_dict = odict() for changeset in suc.reversed_upper_bounded_changelog( repo, changeset_revision ): previous_changeset_revision = str( repo.changectx( changeset ) ) if previous_changeset_revision in reviewed_revision_hashes: - previous_rev, previous_changeset_revision_label = suc.get_rev_label_from_changeset_revision( repo, previous_changeset_revision ) + previous_rev, previous_changeset_revision_label = hg_util.get_rev_label_from_changeset_revision( repo, previous_changeset_revision ) revision_reviews = get_reviews_by_repository_id_changeset_revision( trans, trans.security.encode_id( repository.id ), previous_changeset_revision ) @@ -93,7 +94,7 @@ def get_reviews_by_repository_id_changeset_revision( trans, repository_id, chang def has_previous_repository_reviews( trans, repository, changeset_revision ): """Determine if a repository has a changeset revision review prior to the received changeset revision.""" - repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) ) + repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) ) reviewed_revision_hashes = [ review.changeset_revision for review in repository.reviews ] for changeset in suc.reversed_upper_bounded_changelog( repo, changeset_revision ): previous_changeset_revision = str( repo.changectx( changeset ) ) diff --git a/lib/tool_shed/util/shed_util_common.py b/lib/tool_shed/util/shed_util_common.py index 61661b34c16..6215abcb51a 100644 --- a/lib/tool_shed/util/shed_util_common.py +++ b/lib/tool_shed/util/shed_util_common.py @@ -4,9 +4,6 @@ import re import shutil import string import tempfile -from datetime import datetime -from time import gmtime -from time import strftime from galaxy import util from galaxy.util import asbool from galaxy.util import json @@ -19,6 +16,7 @@ from galaxy.model.orm import or_ import sqlalchemy.orm.exc from tool_shed.util import common_util from tool_shed.util import encoding_util +from tool_shed.util import hg_util from tool_shed.util import xml_util import tool_shed.repository_types.util as rt_util from xml.etree import ElementTree as XmlET @@ -143,7 +141,7 @@ def changeset_is_malicious( trans, id, changeset_revision, **kwd ): def changeset_is_valid( app, repository, changeset_revision ): """Make sure a changeset hash is valid for a specified repository.""" - repo = hg.repository( get_configured_ui(), repository.repo_path( app ) ) + repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( app ) ) for changeset in repo.changelog: changeset_hash = str( repo.changectx( changeset ) ) if changeset_revision == changeset_hash: @@ -167,7 +165,7 @@ def check_or_update_tool_shed_status_for_installed_repository( trans, repository def clone_repository( repository_clone_url, repository_file_dir, ctx_rev ): """Clone the repository up to the specified changeset_revision. No subsequent revisions will be present in the cloned repository.""" try: - commands.clone( get_configured_ui(), + commands.clone( hg_util.get_configured_ui(), str( repository_clone_url ), dest=str( repository_file_dir ), pull=True, @@ -469,14 +467,6 @@ def get_category_by_name( trans, name ): except sqlalchemy.orm.exc.NoResultFound: return None -def get_changectx_for_changeset( repo, changeset_revision, **kwd ): - """Retrieve a specified changectx from a repository.""" - for changeset in repo.changelog: - ctx = repo.changectx( changeset ) - if str( ctx ) == changeset_revision: - return ctx - return None - def get_config( config_file, repo, ctx, dir ): """Return the latest version of config_filename from the repository manifest.""" config_file = strip_path( config_file ) @@ -496,16 +486,6 @@ def get_config_from_disk( config_file, relative_install_dir ): return os.path.abspath( os.path.join( root, name ) ) return None -def get_configured_ui(): - """Configure any desired ui settings.""" - _ui = ui.ui() - # The following will suppress all messages. This is - # the same as adding the following setting to the repo - # hgrc file' [ui] section: - # quiet = True - _ui.setconfig( 'ui', 'quiet', True ) - return _ui - def get_ctx_rev( app, tool_shed_url, name, owner, changeset_revision ): """ Send a request to the tool shed to retrieve the ctx_rev for a repository defined by the @@ -539,7 +519,7 @@ def get_current_repository_metadata_for_changeset_revision( trans, repository, c if repository_metadata: return repository_metadata # The installable changeset_revision may have been changed because it was "moved ahead" in the repository changelog. - repo = hg.repository( get_configured_ui(), repository.repo_path( trans.app ) ) + repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) ) updated_changeset_revision = get_next_downloadable_changeset_revision( repository, repo, after_changeset_revision=changeset_revision ) if updated_changeset_revision: repository_metadata = get_repository_metadata_by_changeset_revision( trans, encoded_repository_id, updated_changeset_revision ) @@ -590,7 +570,7 @@ def get_dependent_downloadable_revisions( trans, repository_metadata ): # record, so updates must be necessary. defined_repository = get_repository_by_name_and_owner( trans.app, name, owner ) defined_repo_dir = defined_repository.repo_path( trans.app ) - defined_repo = hg.repository( get_configured_ui(), defined_repo_dir ) + defined_repo = hg.repository( hg_util.get_configured_ui(), defined_repo_dir ) updated_changeset_revision = \ get_next_downloadable_changeset_revision( defined_repository, defined_repo, @@ -799,7 +779,7 @@ def get_ordered_metadata_changeset_revisions( repository, repo, downloadable=Tru changeset_tups = [] for repository_metadata in metadata_revisions: changeset_revision = repository_metadata.changeset_revision - ctx = get_changectx_for_changeset( repo, changeset_revision ) + ctx = hg_util.get_changectx_for_changeset( repo, changeset_revision ) if ctx: rev = '%04d' % ctx.rev() else: @@ -913,13 +893,6 @@ def get_query_for_setting_metadata_on_repositories( trans, my_writable=False, or return trans.install_model.context.query( trans.install_model.ToolShedRepository ) \ .filter( trans.install_model.ToolShedRepository.table.c.uninstalled == False ) -def get_readable_ctx_date( ctx ): - """Convert the date of the changeset (the received ctx) to a human-readable date.""" - t, tz = ctx.date() - date = datetime( *gmtime( float( t ) - tz )[ :6 ] ) - ctx_date = date.strftime( "%Y-%m-%d" ) - return ctx_date - def get_repo_info_tuple_contents( repo_info_tuple ): """Take care in handling the repo_info_tuple as it evolves over time as new tool shed features are introduced.""" if len( repo_info_tuple ) == 6: @@ -1211,38 +1184,6 @@ def get_reversed_changelog_changesets( repo ): reversed_changelog.insert( 0, changeset ) return reversed_changelog -def get_revision_label( trans, repository, changeset_revision, include_date=True ): - """ - Return a string consisting of the human read-able changeset rev and the changeset revision string - which includes the revision date if the receive include_date is True. - """ - repo = hg.repository( get_configured_ui(), repository.repo_path( trans.app ) ) - ctx = get_changectx_for_changeset( repo, changeset_revision ) - if ctx: - return get_revision_label_from_ctx( ctx, include_date=include_date ) - else: - return "-1:%s" % changeset_revision - -def get_revision_label_from_ctx( ctx, include_date=True ): - if include_date: - return '%s:%s (%s)' % \ - ( str( ctx.rev() ), str( ctx ), str( get_readable_ctx_date( ctx ) ) ) - return '%s:%s' % ( str( ctx.rev() ), str( ctx ) ) - -def get_rev_label_from_changeset_revision( repo, changeset_revision, include_date=True ): - """ - Given a changeset revision hash, return two strings, the changeset rev and the changeset revision hash - which includes the revision date if the receive include_date is True. - """ - ctx = get_changectx_for_changeset( repo, changeset_revision ) - if ctx: - rev = '%04d' % ctx.rev() - label = get_revision_label_from_ctx( ctx, include_date=include_date ) - else: - rev = '-1' - label = "-1:%s" % changeset_revision - return rev, label - def get_shed_tool_conf_dict( app, shed_tool_conf ): """Return the in-memory version of the shed_tool_conf file, which is stored in the config_elems entry in the shed_tool_conf_dict associated with the file.""" for index, shed_tool_conf_dict in enumerate( app.toolbox.shed_tool_confs ): @@ -1434,7 +1375,7 @@ def get_updated_changeset_revisions( trans, name, owner, changeset_revision ): """ repository = get_repository_by_name_and_owner( trans.app, name, owner ) repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) # Get the upper bound changeset revision. upper_bound_changeset_revision = get_next_downloadable_changeset_revision( repository, repo, changeset_revision ) # Build the list of changeset revision hashes defining each available update up to, but excluding, upper_bound_changeset_revision. @@ -1487,7 +1428,7 @@ def handle_email_alerts( trans, repository, content_alert_str='', new_repo_alert that was included in the change set. """ repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) sharable_link = generate_sharable_link_for_repository_in_tool_shed( trans, repository, changeset_revision=None ) smtp_server = trans.app.config.smtp_server if smtp_server and ( new_repo_alert or repository.email_alerts ): @@ -1510,7 +1451,7 @@ def handle_email_alerts( trans, repository, content_alert_str='', new_repo_alert template = new_repo_email_alert_template else: template = email_alert_template - display_date = get_readable_ctx_date( ctx ) + display_date = hg_util.get_readable_ctx_date( ctx ) admin_body = string.Template( template ).safe_substitute( host=trans.request.host, sharable_link=sharable_link, repository_name=repository.name, @@ -1859,7 +1800,7 @@ def update_repository( repo, ctx_rev=None ): # I = ignored # It would be nice if we could use mercurial's purge extension to remove untracked files. The problem is that # purging is not supported by the mercurial API. - commands.update( get_configured_ui(), repo, rev=ctx_rev ) + commands.update( hg_util.get_configured_ui(), repo, rev=ctx_rev ) def update_tool_shed_repository_status( app, tool_shed_repository, status, error_message=None ): """Update the status of a tool shed repository in the process of being installed into Galaxy.""" diff --git a/lib/tool_shed/util/tool_util.py b/lib/tool_shed/util/tool_util.py index cbb9d43f467..6b6f61ad97e 100644 --- a/lib/tool_shed/util/tool_util.py +++ b/lib/tool_shed/util/tool_util.py @@ -15,6 +15,7 @@ from galaxy.util.expressions import ExpressionContext from galaxy.web.form_builder import SelectField from galaxy.tools.actions.upload import UploadToolAction from tool_shed.util import common_util +from tool_shed.util import hg_util from tool_shed.util import xml_util import tool_shed.util.shed_util_common as suc from xml.etree import ElementTree as XmlET @@ -538,7 +539,7 @@ def get_version_lineage_for_tool( trans, repository_id, repository_metadata, gui """ repository = suc.get_repository_by_id( trans, repository_id ) repo_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_dir ) # Initialize the tool lineage version_lineage = [ guid ] # Get all ancestor guids of the received guid. @@ -637,7 +638,7 @@ def handle_sample_files_and_load_tool_from_disk( trans, repo_files_dir, reposito def handle_sample_files_and_load_tool_from_tmp_config( trans, repo, repository_id, changeset_revision, tool_config_filename, work_dir ): tool = None message = '' - ctx = suc.get_changectx_for_changeset( repo, changeset_revision ) + ctx = hg_util.get_changectx_for_changeset( repo, changeset_revision ) # We're not currently doing anything with the returned list of deleted_sample_files here. It is intended to help handle sample files that are in # the manifest, but have been deleted from disk. sample_files, deleted_sample_files = get_list_of_copied_sample_files( repo, ctx, dir=work_dir ) @@ -866,7 +867,7 @@ def load_tool_from_changeset_revision( trans, repository_id, changeset_revision, original_tool_data_path = trans.app.config.tool_data_path repository = suc.get_repository_in_tool_shed( trans, repository_id ) repo_files_dir = repository.repo_path( trans.app ) - repo = hg.repository( suc.get_configured_ui(), repo_files_dir ) + repo = hg.repository( hg_util.get_configured_ui(), repo_files_dir ) message = '' tool = None can_use_disk_file = False diff --git a/scripts/migrate_tools/0010_tools.xml b/scripts/migrate_tools/0010_tools.xml index 51dacf67866..1ead6aceb24 100644 --- a/scripts/migrate_tools/0010_tools.xml +++ b/scripts/migrate_tools/0010_tools.xml @@ -3,17 +3,17 @@ - - + + - - + + - - + + - - + + @@ -24,8 +24,8 @@ - - + + @@ -36,23 +36,23 @@ - - + + - - + + - - + + - - + + @@ -63,11 +63,11 @@ - - + + - - + + @@ -93,8 +93,8 @@ - - + + @@ -135,7 +135,7 @@ - - + + \ No newline at end of file diff --git a/static/scripts/galaxy.library.js b/static/scripts/galaxy.library.js index 1901497a8fb..9b9448b0486 100644 --- a/static/scripts/galaxy.library.js +++ b/static/scripts/galaxy.library.js @@ -2,28 +2,30 @@ // === MAIN GALAXY LIBRARY MODULE ==== // MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM -// global variables -var library_router = null; - // dependencies define([ - "galaxy.masthead", + "galaxy.masthead", "utils/utils", "libs/toastr", "mvc/base-mvc", "mvc/library/library-model", "mvc/library/library-folderlist-view", "mvc/library/library-librarylist-view", - "mvc/library/library-librarytoolbar-view"], -function(mod_masthead, - mod_utils, + "mvc/library/library-librarytoolbar-view", + "mvc/library/library-foldertoolbar-view" + ], +function(mod_masthead, + mod_utils, mod_toastr, mod_baseMVC, mod_library_model, mod_folderlist_view, mod_librarylist_view, - mod_librarytoolbar_view) { + mod_librarytoolbar_view, + mod_foldertoolbar_view + ) { +// ============================================================================ //ROUTER var LibraryRouter = Backbone.Router.extend({ routes: { @@ -44,12 +46,14 @@ var LibraryPrefs = mod_baseMVC.SessionStorageModel.extend({ } }); -// galaxy library wrapper View +// ============================================================================ +// Main controller of Galaxy Library var GalaxyLibrary = Backbone.View.extend({ - toolbarView: null, + libraryToolbarView: null, libraryListView: null, library_router: null, - folderContentView: null, + folderToolbarView: null, + folderListView: null, initialize : function(){ Galaxy.libraries = this; @@ -59,25 +63,26 @@ var GalaxyLibrary = Backbone.View.extend({ this.library_router.on('route:libraries', function() { // initialize and render the toolbar first - Galaxy.libraries.toolbarView = new mod_librarytoolbar_view.ToolbarView(); + Galaxy.libraries.libraryToolbarView = new mod_librarytoolbar_view.LibraryToolbarView(); // initialize and render libraries second Galaxy.libraries.libraryListView = new mod_librarylist_view.LibraryListView(); }); this.library_router.on('route:folder_content', function(id) { - // render folder contents - if (!Galaxy.libraries.folderContentView) {Galaxy.libraries.folderContentView = new mod_folderlist_view.FolderContentView();} - Galaxy.libraries.folderContentView.render({id: id}); + // TODO place caching here, sessionstorage/localstorage? + Galaxy.libraries.folderToolbarView = new mod_foldertoolbar_view.FolderToolbarView({id: id}); + Galaxy.libraries.folderListView = new mod_folderlist_view.FolderListView({id: id}); }); this.library_router.on('route:download', function(folder_id, format) { - if ($('#center').find(':checked').length === 0) { + if ($('#center').find(':checked').length === 0) { + mod_toastr.info('You have to select some datasets to download') // this happens rarely when there is a server/data error and client gets an actual response instead of an attachment // we don't know what was selected so we can't download again, we redirect to the folder provided Galaxy.libraries.library_router.navigate('folders/' + folder_id, {trigger: true, replace: true}); } else { // send download stream - Galaxy.libraries.folderContentView.download(folder_id, format); + Galaxy.libraries.folderToolbarView.download(folder_id, format); Galaxy.libraries.library_router.navigate('folders/' + folder_id, {trigger: false, replace: true}); } }); @@ -86,7 +91,6 @@ var GalaxyLibrary = Backbone.View.extend({ } }); -// return return { GalaxyApp: GalaxyLibrary }; diff --git a/static/scripts/galaxy.workflow_editor.canvas.js b/static/scripts/galaxy.workflow_editor.canvas.js index 820d7f3ddef..c0c9f5b6afe 100644 --- a/static/scripts/galaxy.workflow_editor.canvas.js +++ b/static/scripts/galaxy.workflow_editor.canvas.js @@ -172,101 +172,98 @@ function Node( element ) { } $.extend( Node.prototype, { new_input_terminal : function( input ) { - var t = $("
"); + var t = $("
")[ 0 ]; this.enable_input_terminal( t, input.name, input.extensions, input.multiple ); return t; }, - enable_input_terminal : function( elements, name, types, multiple ) { + enable_input_terminal : function( element, name, types, multiple ) { var node = this; - $(elements).each( function() { - var terminal = this.terminal = new InputTerminal( this, types, multiple ); - terminal.node = node; - terminal.name = name; - $(this).bind( "dropinit", function( e, d ) { - // Accept a dragable if it is an output terminal and has a - // compatible type - return $(d.drag).hasClass( "output-terminal" ) && terminal.can_accept( d.drag.terminal ); - }).bind( "dropstart", function( e, d ) { - if (d.proxy.terminal) { - d.proxy.terminal.connectors[0].inner_color = "#BBFFBB"; - } - }).bind( "dropend", function ( e, d ) { - if (d.proxy.terminal) { - d.proxy.terminal.connectors[0].inner_color = "#FFFFFF"; - } - }).bind( "drop", function( e, d ) { - ( new Connector( d.drag.terminal, terminal ) ).redraw(); - }).bind( "hover", function() { - // If connected, create a popup to allow disconnection - if ( terminal.connectors.length > 0 ) { - // Create callout - var t = $("
") - .css( { display: 'none' } ) - .appendTo( "body" ) - .append( - $("
").append( - $("
").addClass("fa-icon-button fa fa-times").click( function() { - $.each( terminal.connectors, function( _, x ) { - if (x) { - x.destroy(); - } - }); - t.remove(); - }))) - .bind( "mouseleave", function() { - $(this).remove(); - }); - // Position it and show - t.css({ - top: $(this).offset().top - 2, - left: $(this).offset().left - t.width(), - 'padding-right': $(this).width() - }).show(); - } - }); - node.input_terminals[name] = terminal; + + var terminal = element.terminal = new InputTerminal( element, types, multiple ); + terminal.node = node; + terminal.name = name; + $(element).bind( "dropinit", function( e, d ) { + // Accept a dragable if it is an output terminal and has a + // compatible type + return $(d.drag).hasClass( "output-terminal" ) && terminal.can_accept( d.drag.terminal ); + }).bind( "dropstart", function( e, d ) { + if (d.proxy.terminal) { + d.proxy.terminal.connectors[0].inner_color = "#BBFFBB"; + } + }).bind( "dropend", function ( e, d ) { + if (d.proxy.terminal) { + d.proxy.terminal.connectors[0].inner_color = "#FFFFFF"; + } + }).bind( "drop", function( e, d ) { + ( new Connector( d.drag.terminal, terminal ) ).redraw(); + }).bind( "hover", function() { + // If connected, create a popup to allow disconnection + if ( terminal.connectors.length > 0 ) { + // Create callout + var t = $("
") + .css( { display: 'none' } ) + .appendTo( "body" ) + .append( + $("
").append( + $("
").addClass("fa-icon-button fa fa-times").click( function() { + $.each( terminal.connectors, function( _, x ) { + if (x) { + x.destroy(); + } + }); + t.remove(); + }))) + .bind( "mouseleave", function() { + $(this).remove(); + }); + // Position it and show + t.css({ + top: $(element).offset().top - 2, + left: $(element).offset().left - t.width(), + 'padding-right': $(element).width() + }).show(); + } }); + node.input_terminals[name] = terminal; }, - enable_output_terminal : function( elements, name, type ) { + enable_output_terminal : function( element, name, type ) { var node = this; - $(elements).each( function() { - var terminal_element = this; - var terminal = this.terminal = new OutputTerminal( this, type ); - terminal.node = node; - terminal.name = name; - $(this).bind( "dragstart", function( e, d ) { - $( d.available ).addClass( "input-terminal-active" ); - // Save PJAs in the case of change datatype actions. - workflow.check_changes_in_active_form(); - // Drag proxy div - var h = $( '
' ) - .appendTo( "#canvas-container" ).get(0); - // Terminal and connection to display noodle while dragging - h.terminal = new OutputTerminal( h ); - var c = new Connector(); - c.dragging = true; - c.connect( this.terminal, h.terminal ); - return h; - }).bind( "drag", function ( e, d ) { - var onmove = function() { - var po = $(d.proxy).offsetParent().offset(), - x = d.offsetX - po.left, - y = d.offsetY - po.top; - $(d.proxy).css( { left: x, top: y } ); - d.proxy.terminal.redraw(); - // FIXME: global - canvas_manager.update_viewport_overlay(); - }; - onmove(); - $("#canvas-container").get(0).scroll_panel.test( e, onmove ); - }).bind( "dragend", function ( e, d ) { - d.proxy.terminal.connectors[0].destroy(); - $(d.proxy).remove(); - $( d.available ).removeClass( "input-terminal-active" ); - $("#canvas-container").get(0).scroll_panel.stop(); - }); - node.output_terminals[name] = terminal; + var terminal_element = element; + var terminal = element.terminal = new OutputTerminal( element, type ); + terminal.node = node; + terminal.name = name; + $(element).bind( "dragstart", function( e, d ) { + $( d.available ).addClass( "input-terminal-active" ); + // Save PJAs in the case of change datatype actions. + workflow.check_changes_in_active_form(); + // Drag proxy div + var h = $( '
' ) + .appendTo( "#canvas-container" ).get(0); + // Terminal and connection to display noodle while dragging + h.terminal = new OutputTerminal( h ); + var c = new Connector(); + c.dragging = true; + c.connect( element.terminal, h.terminal ); + return h; + }).bind( "drag", function ( e, d ) { + var onmove = function() { + var po = $(d.proxy).offsetParent().offset(), + x = d.offsetX - po.left, + y = d.offsetY - po.top; + $(d.proxy).css( { left: x, top: y } ); + d.proxy.terminal.redraw(); + // FIXME: global + canvas_manager.update_viewport_overlay(); + }; + onmove(); + $("#canvas-container").get(0).scroll_panel.test( e, onmove ); + }).bind( "dragend", function ( e, d ) { + d.proxy.terminal.connectors[0].destroy(); + $(d.proxy).remove(); + $( d.available ).removeClass( "input-terminal-active" ); + $("#canvas-container").get(0).scroll_panel.stop(); }); + node.output_terminals[name] = terminal; }, redraw : function () { $.each( this.input_terminals, function( _, t ) { @@ -342,7 +339,7 @@ $.extend( Node.prototype, { } $.each( data.data_outputs, function( i, output ) { var t = $( "
" ); - node.enable_output_terminal( t, output.name, output.extensions ); + node.enable_output_terminal( t[ 0 ], output.name, output.extensions ); var label = output.name; if ( output.extensions.indexOf( 'input' ) < 0 ) { label = label + " (" + output.extensions.join(", ") + ")"; @@ -422,7 +419,6 @@ $.extend( Node.prototype, { // Update input rows var old_body = el.find( "div.inputs" ); var new_body = $("
"); - var old = old_body.find( "div.input-data-row"); $.each( data.data_inputs, function( i, input ) { var t = node.new_input_terminal( input ); // If already connected save old connection @@ -430,8 +426,8 @@ $.extend( Node.prototype, { $(this).find( ".input-terminal" ).each( function() { var c = this.terminal.connectors[0]; if ( c ) { - t[0].terminal.connectors[0] = c; - c.handle2 = t[0].terminal; + t.terminal.connectors[0] = c; + c.handle2 = t.terminal; } }); $(this).remove(); @@ -893,6 +889,18 @@ function prebuild_node( type, title_text, tool_id ) { return node; } +function add_node( type, title_text, tool_id ) { + // Abstraction for use by galaxy.workflow.js to hide + // some editor details from workflow code and reduce duplication + // between add_node_for_tool and add_node_for_module. + var node = prebuild_node( type, title_text, tool_id ); + workflow.add_node( node ); + workflow.fit_canvas_to_nodes(); + canvas_manager.draw_overview(); + workflow.activate_node( node ); + return node; +} + var ext_to_type = null; var type_to_type = null; diff --git a/static/scripts/galaxy.workflows.js b/static/scripts/galaxy.workflows.js index 8a027621665..3dce5a6bfaa 100644 --- a/static/scripts/galaxy.workflows.js +++ b/static/scripts/galaxy.workflows.js @@ -320,11 +320,7 @@ function scroll_to_nodes() { // Add a new step to the workflow by tool id function add_node_for_tool( id, title ) { - var node = prebuild_node( 'tool', title, id ); - workflow.add_node( node ); - workflow.fit_canvas_to_nodes(); - canvas_manager.draw_overview(); - workflow.activate_node( node ); + node = add_node( 'tool', title, id ); $.ajax( { url: get_new_module_info_url, data: { type: "tool", tool_id: id, "_": "true" }, @@ -344,11 +340,7 @@ function add_node_for_tool( id, title ) { } function add_node_for_module( type, title ) { - node = prebuild_node( type, title ); - workflow.add_node( node ); - workflow.fit_canvas_to_nodes(); - canvas_manager.draw_overview(); - workflow.activate_node( node ); + node = add_node( type, title ); $.ajax( { url: get_new_module_info_url, data: { type: type, "_": "true" }, diff --git a/static/scripts/mvc/library/library-folderlist-view.js b/static/scripts/mvc/library/library-folderlist-view.js index 21e8f289c40..a0bd9a3f8a7 100644 --- a/static/scripts/mvc/library/library-folderlist-view.js +++ b/static/scripts/mvc/library/library-folderlist-view.js @@ -1,458 +1,126 @@ // dependencies define([ - "galaxy.masthead", + "galaxy.masthead", "utils/utils", "libs/toastr", - "mvc/library/library-model"], -function(mod_masthead, - mod_utils, + "mvc/library/library-model", + "mvc/library/library-folderrow-view"], +function(mod_masthead, + mod_utils, mod_toastr, - mod_library_model) { + mod_library_model, + mod_library_folderrow_view) { - //main view for folder browsing -var FolderContentView = Backbone.View.extend({ - // main element definition - el : '#center', - // progress percentage - progress: 0, - // progress rate per one item - progressStep: 1, - // last selected history in modal for UX - lastSelectedHistory: '', - // self modal - modal : null, - // loaded folders - folders : null, +var FolderListView = Backbone.View.extend({ + // main element definition + el : '#folder_items_element', + // progress percentage + progress: 0, + // progress rate per one item + progressStep: 1, + // self modal + modal : null, + folderContainer: null, + + // event binding + events: { + 'click #select-all-checkboxes' : 'selectAll', + 'click .dataset_row' : 'selectClickedRow' + }, // initialize - initialize : function(){ - this.folders = []; + initialize : function(options){ + var that = this; + this.options = _.defaults(this.options || {}, options); this.queue = jQuery.Deferred(); this.queue.resolve(); - }, - -// MMMMMMMMMMMMMMMMMM -// === TEMPLATES ==== -// MMMMMMMMMMMMMMMMMM - - // main template for folder browsing - templateFolder : function (){ - var tmpl_array = []; - - // CONTAINER - tmpl_array.push('
'); - tmpl_array.push('

Data Libraries Beta Test. This is work in progress. Please report problems & ideas via email and Trello.

'); - - // TOOLBAR - tmpl_array.push('
'); - tmpl_array.push(' '); - tmpl_array.push(' '); - tmpl_array.push(' '); - - tmpl_array.push('
'); - - // BREADCRUMBS - tmpl_array.push(''); - - - // FOLDER CONTENT - tmpl_array.push(''); - tmpl_array.push(' '); - tmpl_array.push(' '); - tmpl_array.push(' '); - tmpl_array.push(' '); - tmpl_array.push(' '); - tmpl_array.push(' '); - tmpl_array.push(' '); - tmpl_array.push(' '); - tmpl_array.push(' '); - tmpl_array.push(' '); - tmpl_array.push(' '); - tmpl_array.push(' '); - tmpl_array.push(' '); - tmpl_array.push(' '); - tmpl_array.push(' '); - tmpl_array.push(' '); - tmpl_array.push(' <% _.each(items, function(content_item) { %>'); - tmpl_array.push(' <% if (content_item.get("type") === "folder") { %>'); // folder - tmpl_array.push(' '); - tmpl_array.push(' '); - tmpl_array.push(' '); - tmpl_array.push(' '); - tmpl_array.push(' '); - tmpl_array.push(' '); // size - tmpl_array.push(' '); // time updated - tmpl_array.push(' '); - tmpl_array.push(' <% } else { %>'); - tmpl_array.push(' '); - tmpl_array.push(' '); - tmpl_array.push(' '); - tmpl_array.push(' '); // dataset - tmpl_array.push(' '); // data type - tmpl_array.push(' '); // size - tmpl_array.push(' '); // time updated - tmpl_array.push(' '); - tmpl_array.push(' <% } %> '); - tmpl_array.push(' <% }); %>'); - tmpl_array.push(' '); - tmpl_array.push(' '); - tmpl_array.push('
namedata typesizedate (UTC)
" title="Go to parent folder" class="btn_open_folder btn btn-default btn-xs">..
'); - tmpl_array.push(' '); - tmpl_array.push(' '); - tmpl_array.push(' <%- content_item.get("name") %>'); - tmpl_array.push(' <% if (content_item.get("item_count") === 0) { %>'); // empty folder - tmpl_array.push(' (empty folder)'); - tmpl_array.push(' <% } %>'); - tmpl_array.push(' folder<%= _.escape(content_item.get("item_count")) %> item(s)<%= _.escape(content_item.get("time_updated")) %>
'); - tmpl_array.push(' '); - tmpl_array.push(' <%- content_item.get("name") %><%= _.escape(content_item.get("data_type")) %><%= _.escape(content_item.get("readable_size")) %><%= _.escape(content_item.get("time_updated")) %>
'); - - tmpl_array.push('
'); - return tmpl_array.join(''); - }, - templateDatasetModal : function(){ - var tmpl_array = []; - - tmpl_array.push(''); - - return tmpl_array.join(''); - }, - - templateHistorySelectInModal : function(){ - var tmpl_array = []; - - tmpl_array.push(''); - tmpl_array.push('Select history: '); - tmpl_array.push(''); - tmpl_array.push(''); - - return tmpl_array.join(''); - }, - - templateBulkImportInModal : function(){ - var tmpl_array = []; - - tmpl_array.push(''); - tmpl_array.push('Select history: '); - tmpl_array.push(''); - tmpl_array.push(''); - - return tmpl_array.join(''); - }, - - templateProgressBar : function (){ - var tmpl_array = []; - - tmpl_array.push('
'); - tmpl_array.push('Importing selected datasets to history <%= _.escape(history_name) %>'); - tmpl_array.push('
'); - tmpl_array.push('
'); - tmpl_array.push('
'); - tmpl_array.push(' 0% Complete'); - tmpl_array.push('
'); - tmpl_array.push('
'); - tmpl_array.push(''); - - return tmpl_array.join(''); - }, - - templateNewFolderInModal: function(){ - tmpl_array = []; - - tmpl_array.push('
'); - tmpl_array.push('
'); - tmpl_array.push(''); - tmpl_array.push(''); - tmpl_array.push('
'); - tmpl_array.push('
'); - - return tmpl_array.join(''); - }, - -// MMMMMMMMMMMMMMM -// === EVENTS ==== -// MMMMMMMMMMMMMMM - - // event binding - events: { - 'click #select-all-checkboxes' : 'selectAll', - 'click #toolbtn_bulk_import' : 'modalBulkImport', - 'click #toolbtn_dl' : 'bulkDownload', - 'click #toolbtn_create_folder' : 'createFolderFromModal', - 'click .library-dataset' : 'showDatasetDetails', - 'click .dataset_row' : 'selectClickedRow' - }, - -// MMMMMMMMMMMMMMMMMM -// === FUNCTIONS ==== -// MMMMMMMMMMMMMMMMMM - - //render the folder view - render: function (options) { - //hack to show scrollbars - $("#center").css('overflow','auto'); - - view = this; - var that = this; - - var folderContainer = new mod_library_model.FolderContainer({id: options.id}); - folderContainer.url = folderContainer.attributes.urlRoot + options.id + '/contents'; - - folderContainer.fetch({ - success: function (container) { - - // prepare nice size strings - for (var i = 0; i < folderContainer.attributes.folder.models.length; i++) { - var model = folderContainer.attributes.folder.models[i] - if (model.get('type') === 'file'){ - model.set('readable_size', that.size_to_string(model.get('file_size'))) - } - }; - - // find the upper id - var path = folderContainer.full_path; - var upper_folder_id; - if (path.length === 1){ // library is above us - upper_folder_id = 0; - } else { - upper_folder_id = path[path.length-2][0]; - } - - var template = _.template(that.templateFolder(), { path: folderContainer.full_path, items: folderContainer.attributes.folder.models, id: options.id, upper_folder_id: upper_folder_id }); - // var template = _.template(that.templateFolder(), { path: folderContainer.full_path, items: folderContainer.attributes.folder.models, id: options.id }); - that.$el.html(template); + this.folderContainer = new mod_library_model.FolderContainer({id: this.options.id}); + this.folderContainer.url = this.folderContainer.attributes.urlRoot + this.options.id + '/contents'; + this.folderContainer.fetch({ + success: function (folderContainer) { + that.render(); }, - error: function(){ - mod_toastr.error('An error occured :('); - } - }) - }, + error: function(){ + mod_toastr.error('An error occured :('); + } + }); + }, + + render: function (options) { + this.options = _.defaults(this.options || {}, options); + var template = this.templateFolder(); + var contains_file = false; + + // TODO move to server + // prepare nice size strings + for (var i = 0; i < this.folderContainer.attributes.folder.models.length; i++) { + var model = this.folderContainer.attributes.folder.models[i]; + if (model.get('type') === 'file'){ + contains_file = true; + model.set('readable_size', this.size_to_string(model.get('file_size'))); + } + } + + // TODO move to server + // find the upper id in the full path + var path = this.folderContainer.attributes.metadata.full_path; + var upper_folder_id; + if (path.length === 1){ // the library is above us + upper_folder_id = 0; + } else { + upper_folder_id = path[path.length-2][0]; + } + + this.$el.html(template({ path: this.folderContainer.attributes.metadata.full_path, items: this.folderContainer.attributes.folder.models, id: this.options.id, upper_folder_id: upper_folder_id })); + + if (this.folderContainer.attributes.folder.models.length > 0){ + this.renderRows(); + } + if (this.folderContainer.attributes.metadata.can_add_library_item === true){ + Galaxy.libraries.folderToolbarView.configureElements({ can_add_library_item: this.folderContainer.attributes.metadata.can_add_library_item, contains_file: contains_file }); + } + + // initialize the library tooltips + $("#center [data-toggle]").tooltip(); + //hack to show scrollbars + $("#center").css('overflow','auto'); + }, + + renderRows: function(){ + for (var i = 0; i < this.folderContainer.attributes.folder.models.length; i++) { + var folder_item = this.folderContainer.attributes.folder.models[i]; + var rowView = new mod_library_folderrow_view.FolderRowView(folder_item); + this.$el.find('#folder_list_body').append(rowView.el); + } + }, // convert size to nice string - size_to_string : function (size) - { - // identify unit - var unit = ""; - if (size >= 100000000000) { size = size / 100000000000; unit = "TB"; } else - if (size >= 100000000) { size = size / 100000000; unit = "GB"; } else - if (size >= 100000) { size = size / 100000; unit = "MB"; } else - if (size >= 100) { size = size / 100; unit = "KB"; } else - { size = size * 10; unit = "b"; } - // return formatted string - return (Math.round(size) / 10) + unit; - }, - - //show modal with current dataset info - showDatasetDetails : function(event){ - // prevent default - event.preventDefault(); - - //TODO check whether we already have the data - - //load the ID of the row - var id = $(event.target).parent().parent().parent().attr('id'); - if (typeof id === 'undefined'){ - id = $(event.target).parent().attr('id'); - } - if (typeof id === 'undefined'){ - id = $(event.target).parent().parent().attr('id') - } - - //create new item - var item = new mod_library_model.Item(); - var histories = new mod_library_model.GalaxyHistories(); - item.id = id; - var self = this; - - //fetch the dataset info - item.fetch({ - success: function (item) { - // TODO can render here already - //fetch user histories for import purposes - histories.fetch({ - success: function (histories){ - self.renderModalAfterFetch(item, histories) - }, - error: function(){ - mod_toastr.error('An error occured during fetching histories:('); - self.renderModalAfterFetch(item) - } - }); - }, - error: function(){ - mod_toastr.error('An error occured during loading dataset details :('); - } - }); - }, - - // show the current dataset in a modal - renderModalAfterFetch : function(item, histories){ - var size = this.size_to_string(item.get('file_size')); - var template = _.template(this.templateDatasetModal(), { item : item, size : size }); - // make modal - var self = this; - this.modal = Galaxy.modal; - this.modal.show({ - closing_events : true, - title : 'Dataset Details', - body : template, - buttons : { - 'Import' : function() { self.importCurrentIntoHistory() }, - 'Download' : function() { self.downloadCurrent() }, - 'Close' : function() { self.modal.hide() } - } - }); - - $(".peek").html('Peek:' + item.get("peek")); - - // show the import-into-history footer only if the request for histories succeeded - if (typeof history.models !== undefined){ - var history_footer_tmpl = _.template(this.templateHistorySelectInModal(), {histories : histories.models}); - $(this.modal.elMain).find('.buttons').prepend(history_footer_tmpl); - // preset last selected history if we know it - if (self.lastSelectedHistory.length > 0) { - $(this.modal.elMain).find('#dataset_import_single').val(self.lastSelectedHistory); - } - } - }, - - // download dataset shown currently in modal - downloadCurrent : function(){ - //disable the buttons - this.modal.disableButton('Import'); - this.modal.disableButton('Download'); - - var library_dataset_id = []; - library_dataset_id.push($('#id_row').attr('data-id')); - var url = '/api/libraries/datasets/download/uncompressed'; - var data = {'ldda_ids' : library_dataset_id}; - - // we assume the view is existent - folderContentView.processDownload(url, data); - this.modal.enableButton('Import'); - this.modal.enableButton('Download'); - }, - - // import dataset shown currently in modal into selected history - importCurrentIntoHistory : function(){ - //disable the buttons - this.modal.disableButton('Import'); - this.modal.disableButton('Download'); - - var history_id = $(this.modal.elMain).find('select[name=dataset_import_single] option:selected').val(); - this.lastSelectedHistory = history_id; //save selected history for further use - - var library_dataset_id = $('#id_row').attr('data-id'); - var historyItem = new mod_library_model.HistoryItem(); - var self = this; - historyItem.url = historyItem.urlRoot + history_id + '/contents'; - - // save the dataset into selected history - historyItem.save({ content : library_dataset_id, source : 'library' }, { success : function(){ - mod_toastr.success('Dataset imported'); - //enable the buttons - self.modal.enableButton('Import'); - self.modal.enableButton('Download'); - }, error : function(){ - mod_toastr.error('An error occured! Dataset not imported. Please try again.') - //enable the buttons - self.modal.enableButton('Import'); - self.modal.enableButton('Download'); - } - }); - }, + size_to_string : function (size){ + // identify unit + var unit = ""; + if (size >= 100000000000) { size = size / 100000000000; unit = "TB"; } else + if (size >= 100000000) { size = size / 100000000; unit = "GB"; } else + if (size >= 100000) { size = size / 100000; unit = "MB"; } else + if (size >= 100) { size = size / 100; unit = "KB"; } else + { size = size * 10; unit = "b"; } + // return formatted string + return (Math.round(size) / 10) + unit; + }, // select all datasets selectAll : function (event) { var selected = event.target.checked; that = this; // Iterate each checkbox - $(':checkbox').each(function () { - this.checked = selected; + $(':checkbox').each(function() { + this.checked = selected; $row = $(this.parentElement.parentElement); // Change color of selected/unselected (selected) ? that.makeDarkRow($row) : that.makeWhiteRow($row); }); // Show the tools in menu - this.checkTools(); + // this.checkTools(); }, // Check checkbox on row itself or row checkbox click @@ -485,7 +153,7 @@ var FolderContentView = Backbone.View.extend({ this.makeWhiteRow($row); } } - this.checkTools(); + // this.checkTools(); }, makeDarkRow: function($row){ @@ -507,207 +175,56 @@ var FolderContentView = Backbone.View.extend({ $row.find('span').removeClass('fa-file'); }, - // show toolbar in case something is selected - checkTools : function(){ - var checkedValues = $('#folder_table').find(':checked'); - if(checkedValues.length > 0){ - $('#toolbtn_bulk_import').show(); - $('#toolbtn_dl').show(); - } else { - $('#toolbtn_bulk_import').hide(); - $('#toolbtn_dl').hide(); - } - }, +// MMMMMMMMMMMMMMMMMM +// === TEMPLATES ==== +// MMMMMMMMMMMMMMMMMM - // show bulk import modal - modalBulkImport : function(){ - var self = this; - // fetch histories - var histories = new mod_library_model.GalaxyHistories(); - histories.fetch({ - success: function (histories){ - // make modal - var history_modal_tmpl = _.template(self.templateBulkImportInModal(), {histories : histories.models}); - self.modal = Galaxy.modal; - self.modal.show({ - closing_events : true, - title : 'Import into History', - body : history_modal_tmpl, - buttons : { - 'Import' : function() {self.importAllIntoHistory()}, - 'Close' : function() {self.modal.hide();} - } - }); - }, - error: function(){ - mod_toastr.error('An error occured :('); - } - }); - }, + // main template for folder browsing + templateFolder : function (){ + var tmpl_array = []; - // import all selected datasets into history - importAllIntoHistory : function (){ - //disable the button to prevent multiple submission - this.modal.disableButton('Import'); + // BREADCRUMBS + tmpl_array.push(''); - var history_id = $("select[name=dataset_import_bulk] option:selected").val(); - var history_name = $("select[name=dataset_import_bulk] option:selected").text(); + // FOLDER CONTENT + tmpl_array.push(''); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push(' '); - var dataset_ids = []; - $('#folder_table').find(':checked').each(function(){ - if (this.parentElement.parentElement.id != '') { - dataset_ids.push(this.parentElement.parentElement.id); - } - }); - var progress_bar_tmpl = _.template(this.templateProgressBar(), { history_name : history_name }); - $(this.modal.elMain).find('.modal-body').html(progress_bar_tmpl); + tmpl_array.push(' '); + tmpl_array.push('
namedata typesizedate (UTC)
" title="Go to parent folder" class="btn_open_folder btn btn-default btn-xs">..
'); - // init the progress bar - var progressStep = 100 / dataset_ids.length; - this.initProgress(progressStep); - - // prepare the dataset objects to be imported - var datasets_to_import = []; - for (var i = dataset_ids.length - 1; i >= 0; i--) { - library_dataset_id = dataset_ids[i]; - var historyItem = new mod_library_model.HistoryItem(); - var self = this; - historyItem.url = historyItem.urlRoot + history_id + '/contents'; - historyItem.content = library_dataset_id; - historyItem.source = 'library'; - datasets_to_import.push(historyItem); - }; - - // call the recursive function to call ajax one after each other (request FIFO queue) - this.chainCall(datasets_to_import); - }, - - chainCall: function(history_item_set){ - var self = this; - var popped_item = history_item_set.pop(); - if (typeof popped_item === "undefined") { - mod_toastr.success('All datasets imported'); - this.modal.hide(); - return - } - var promise = $.when(popped_item.save({content: popped_item.content, source: popped_item.source})).done(function(a1){ - self.updateProgress(); - // responses.push(a1); - self.chainCall(history_item_set); - }); - }, - - initProgress: function(progressStep){ - this.progress = 0; - this.progressStep = progressStep; - }, - updateProgress: function(){ - this.progress += this.progressStep; - $('.progress-bar-import').width(Math.round(this.progress) + '%'); - txt_representation = Math.round(this.progress) + '% Complete'; - $('.completion_span').text(txt_representation); - }, - - - - // download selected datasets - download : function(folder_id, format){ - var dataset_ids = []; - $('#folder_table').find(':checked').each(function(){ - if (this.parentElement.parentElement.id != '') { - dataset_ids.push(this.parentElement.parentElement.id); - } - }); - - var url = '/api/libraries/datasets/download/' + format; - var data = {'ldda_ids' : dataset_ids}; - this.processDownload(url, data, 'get'); - }, - - // create hidden form and submit through POST to initialize download - processDownload: function(url, data, method){ - //url and data options required - if( url && data ){ - //data can be string of parameters or array/object - data = typeof data == 'string' ? data : $.param(data); - //split params into form inputs - var inputs = ''; - $.each(data.split('&'), function(){ - var pair = this.split('='); - inputs+=''; - }); - //send request - $('
'+inputs+'
') - .appendTo('body').submit().remove(); - - mod_toastr.info('Your download will begin soon'); - }; - }, - - // shows modal for creating folder - createFolderFromModal: function(){ - event.preventDefault(); - event.stopPropagation(); - - // create modal - var self = this; - this.modal = Galaxy.modal; - this.modal.show({ - closing_events : true, - title : 'Create New Folder', - body : this.templateNewFolderInModal(), - buttons : { - 'Create' : function() {self.create_new_folder_event()}, - 'Close' : function() {self.modal.hide(); self.modal = null;} - } - }); - }, - - // create the new folder from modal - create_new_folder_event: function(){ - var folderDetails = this.serialize_new_folder(); - if (this.validate_new_folder(folderDetails)){ - var folder = new mod_library_model.FolderAsModel(); - - url_items = Backbone.history.fragment.split('/'); - current_folder_id = url_items[url_items.length-1]; - folder.url = folder.urlRoot + '/' + current_folder_id ; - - var self = this; - folder.save(folderDetails, { - success: function (folder) { - self.modal.hide(); - mod_toastr.success('Folder created'); - self.render({id: current_folder_id}); - }, - error: function(){ - mod_toastr.error('An error occured :('); - } - }); - } else { - mod_toastr.error('Folder\'s name is missing'); - } - return false; - }, - - // serialize data from the form - serialize_new_folder : function(){ - return { - name: $("input[name='Name']").val(), - description: $("input[name='Description']").val() - }; - }, - - // validate new library info - validate_new_folder: function(folderDetails){ - return folderDetails.name !== ''; + return _.template(tmpl_array.join('')); } }); -// return return { - FolderContentView: FolderContentView + FolderListView: FolderListView }; }); diff --git a/static/scripts/mvc/library/library-folderrow-view.js b/static/scripts/mvc/library/library-folderrow-view.js new file mode 100644 index 00000000000..70b4fb9b61f --- /dev/null +++ b/static/scripts/mvc/library/library-folderrow-view.js @@ -0,0 +1,310 @@ +// dependencies +define([ + "galaxy.masthead", + "utils/utils", + "libs/toastr", + "mvc/library/library-model"], +function(mod_masthead, + mod_utils, + mod_toastr, + mod_library_model) { + +// galaxy library row view +var FolderRowView = Backbone.View.extend({ + // last selected history in modal for UX + lastSelectedHistory: '', + + events: { + 'click .library-dataset' : 'showDatasetDetails' + }, + + options: { + type: null + }, + + initialize : function(folder_item){ + this.render(folder_item); + }, + + render: function(folder_item){ + // if (typeof folder_item === 'undefined'){ + // folder_item = Galaxy.libraries.libraryFolderView.collection.get(this.$el.data('id')); + // } + var template = null; + if (folder_item.get('type') === 'folder'){ + this.options.type = 'folder'; + template = this.templateRowFolder(); + } else { + this.options.type = 'file'; + template = this.templateRowFile(); + } + this.setElement(template({content_item:folder_item})); + this.$el.show(); + return this; + }, + + //show modal with current dataset info + showDatasetDetails : function(event){ + // prevent default + event.preventDefault(); + + var id = this.id; + + //create new item + var item = new mod_library_model.Item(); + var histories = new mod_library_model.GalaxyHistories(); + item.id = id; + var self = this; + + //fetch the dataset info + item.fetch({ + success: function (item) { + // TODO can start rendering here already + //fetch user histories for import purposes + histories.fetch({ + success: function (histories){ + self.renderModalAfterFetch(item, histories); + }, + error: function(){ + mod_toastr.error('An error occured during fetching histories:('); + self.renderModalAfterFetch(item); + } + }); + }, + error: function(){ + mod_toastr.error('An error occured during loading dataset details :('); + } + }); +}, + + // show the current dataset in a modal + renderModalAfterFetch : function(item, histories){ + var size = this.size_to_string(item.get('file_size')); + var template = _.template(this.templateDatasetModal(), { item : item, size : size }); + // make modal + var self = this; + this.modal = Galaxy.modal; + this.modal.show({ + closing_events : true, + title : 'Dataset Details', + body : template, + buttons : { + 'Import' : function() { self.importCurrentIntoHistory(); }, + 'Download' : function() { self.downloadCurrent(); }, + 'Close' : function() { self.modal.hide(); } + } + }); + + $(".peek").html(item.get("peek")); + + // show the import-into-history footer only if the request for histories succeeded + if (typeof history.models !== undefined){ + var history_footer_tmpl = _.template(this.templateHistorySelectInModal(), {histories : histories.models}); + $(this.modal.elMain).find('.buttons').prepend(history_footer_tmpl); + // preset last selected history if we know it + if (self.lastSelectedHistory.length > 0) { + $(this.modal.elMain).find('#dataset_import_single').val(self.lastSelectedHistory); + } + } + }, + + // TODO this is dup func, unify + // convert size to nice string + size_to_string : function (size){ + // identify unit + var unit = ""; + if (size >= 100000000000) { size = size / 100000000000; unit = "TB"; } else + if (size >= 100000000) { size = size / 100000000; unit = "GB"; } else + if (size >= 100000) { size = size / 100000; unit = "MB"; } else + if (size >= 100) { size = size / 100; unit = "KB"; } else + { size = size * 10; unit = "b"; } + // return formatted string + return (Math.round(size) / 10) + unit; + }, + + // download dataset shown currently in modal + downloadCurrent : function(){ + //disable the buttons + this.modal.disableButton('Import'); + this.modal.disableButton('Download'); + + var library_dataset_id = []; + library_dataset_id.push($('#id_row').attr('data-id')); + var url = '/api/libraries/datasets/download/uncompressed'; + var data = {'ldda_ids' : library_dataset_id}; + + this.processDownload(url, data); + this.modal.enableButton('Import'); + this.modal.enableButton('Download'); + }, + + // TODO this is dup func, unify + // create hidden form and submit through POST to initialize download + processDownload: function(url, data, method){ + //url and data options required + if( url && data ){ + //data can be string of parameters or array/object + data = typeof data == 'string' ? data : $.param(data); + //split params into form inputs + var inputs = ''; + $.each(data.split('&'), function(){ + var pair = this.split('='); + inputs+=''; + }); + //send request + $('
'+inputs+'
') + .appendTo('body').submit().remove(); + + mod_toastr.info('Your download will begin soon'); + } + }, + + // import dataset shown currently in modal into selected history + importCurrentIntoHistory : function(){ + //disable the buttons + this.modal.disableButton('Import'); + this.modal.disableButton('Download'); + + var history_id = $(this.modal.elMain).find('select[name=dataset_import_single] option:selected').val(); + this.lastSelectedHistory = history_id; //save selected history for further use + + var library_dataset_id = $('#id_row').attr('data-id'); + var historyItem = new mod_library_model.HistoryItem(); + var self = this; + historyItem.url = historyItem.urlRoot + history_id + '/contents'; + + // save the dataset into selected history + historyItem.save({ content : library_dataset_id, source : 'library' }, { success : function(){ + mod_toastr.success('Dataset imported'); + //enable the buttons + self.modal.enableButton('Import'); + self.modal.enableButton('Download'); + }, error : function(){ + mod_toastr.error('An error occured! Dataset not imported. Please try again.'); + //enable the buttons + self.modal.enableButton('Import'); + self.modal.enableButton('Download'); + } + }); + }, + + templateRowFolder: function() { + tmpl_array = []; + + tmpl_array.push(''); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push(' <%- content_item.get("name") %>'); + tmpl_array.push(' <% if (content_item.get("item_count") === 0) { %>'); // empty folder + tmpl_array.push(' (empty folder)'); + tmpl_array.push(' <% } %>'); + tmpl_array.push(' '); + tmpl_array.push(' folder'); + tmpl_array.push(' <%= _.escape(content_item.get("item_count")) %> item(s)'); // size + tmpl_array.push(' <%= _.escape(content_item.get("time_updated")) %>'); // time updated + tmpl_array.push(''); + + return _.template(tmpl_array.join('')); + }, + + templateRowFile: function(){ + tmpl_array = []; + + tmpl_array.push(''); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push(' <%- content_item.get("name") %>'); // dataset + tmpl_array.push(' <%= _.escape(content_item.get("data_type")) %>'); // data type + tmpl_array.push(' <%= _.escape(content_item.get("readable_size")) %>'); // size + tmpl_array.push(' <%= _.escape(content_item.get("time_updated")) %>'); // time updated + tmpl_array.push(''); + + return _.template(tmpl_array.join('')); + }, + +templateDatasetModal : function(){ + var tmpl_array = []; + + tmpl_array.push(''); + + return tmpl_array.join(''); +}, + +templateHistorySelectInModal : function(){ + var tmpl_array = []; + + tmpl_array.push(''); + tmpl_array.push('Select history: '); + tmpl_array.push(''); + tmpl_array.push(''); + + return tmpl_array.join(''); +} + +}); + +return { + FolderRowView: FolderRowView +}; + +}); diff --git a/static/scripts/mvc/library/library-foldertoolbar-view.js b/static/scripts/mvc/library/library-foldertoolbar-view.js new file mode 100644 index 00000000000..7b702a782dd --- /dev/null +++ b/static/scripts/mvc/library/library-foldertoolbar-view.js @@ -0,0 +1,320 @@ +// dependencies +define([ + "galaxy.masthead", + "utils/utils", + "libs/toastr", + "mvc/library/library-model"], +function(mod_masthead, + mod_utils, + mod_toastr, + mod_library_model) { + +var FolderToolbarView = Backbone.View.extend({ + el: '#center', + + events: { + 'click #toolbtn_create_folder' : 'createFolderFromModal', + 'click #toolbtn_bulk_import' : 'modalBulkImport' + }, + + defaults: { + 'can_add_library_item' : false, + 'contains_file' : false + }, + + modal : null, + + initialize: function(options){ + this.options = _.defaults(options || {}, this.defaults); + this.render(); + }, + + render: function(options){ + this.options = _.extend(this.options, options); + var toolbar_template = this.templateToolBar(); + var is_admin = Galaxy.currUser.isAdmin(); + this.$el.html(toolbar_template({id: this.options.id, admin_user: is_admin})); + }, + + configureElements: function(options){ + this.options = _.extend(this.options, options); + if (this.options.can_add_library_item === true){ + $('#toolbtn_create_folder').show(); + $('#toolbtn_upload_files').show(); + } + if (this.options.contains_file === true){ + $('#toolbtn_bulk_import').show(); + $('#toolbtn_dl').show(); + } + this.$el.find('[data-toggle]').tooltip(); + }, + + // shows modal for creating folder + createFolderFromModal: function(){ + event.preventDefault(); + event.stopPropagation(); + + // create modal + var self = this; + var template = this.templateNewFolderInModal(); + this.modal = Galaxy.modal; + this.modal.show({ + closing_events : true, + title : 'Create New Folder', + body : template(), + buttons : { + 'Create' : function() {self.create_new_folder_event();}, + 'Close' : function() {self.modal.hide(); self.modal = null;} + } + }); + }, + + // create the new folder from modal + create_new_folder_event: function(){ + var folderDetails = this.serialize_new_folder(); + if (this.validate_new_folder(folderDetails)){ + var folder = new mod_library_model.FolderAsModel(); + url_items = Backbone.history.fragment.split('/'); + current_folder_id = url_items[url_items.length-1]; + folder.url = folder.urlRoot + '/' + current_folder_id ; + + var self = this; + folder.save(folderDetails, { + success: function (folder) { + self.modal.hide(); + mod_toastr.success('Folder created'); + Galaxy.libraries.folderListView.render({id: current_folder_id}); + }, + error: function(){ + mod_toastr.error('An error occured :('); + } + }); + } else { + mod_toastr.error('Folder\'s name is missing'); + } + return false; + }, + + // serialize data from the modal + serialize_new_folder : function(){ + return { + name: $("input[name='Name']").val(), + description: $("input[name='Description']").val() + }; + }, + + // validate new folder info + validate_new_folder: function(folderDetails){ + return folderDetails.name !== ''; + }, + + + // show bulk import modal + modalBulkImport : function(){ + var checkedValues = $('#folder_table').find(':checked'); + if(checkedValues.length === 0){ + mod_toastr.info('You have to select some datasets first'); + } else { + var self = this; + // fetch histories + var template = this.templateBulkImportInModal(); + var histories = new mod_library_model.GalaxyHistories(); + histories.fetch({ + success: function (histories){ + // make modal + // var history_modal_tmpl = template({histories : histories.models}); + self.modal = Galaxy.modal; + self.modal.show({ + closing_events : true, + title : 'Import into History', + body : template({histories : histories.models}), + buttons : { + 'Import' : function() {self.importAllIntoHistory();}, + 'Close' : function() {self.modal.hide();} + } + }); + }, + error: function(){ + mod_toastr.error('An error occured :('); + } + }); + } + }, + + // import all selected datasets into history + importAllIntoHistory : function (){ + //disable the button to prevent multiple submission + this.modal.disableButton('Import'); + + var history_id = $("select[name=dataset_import_bulk] option:selected").val(); + var history_name = $("select[name=dataset_import_bulk] option:selected").text(); + + var dataset_ids = []; + $('#folder_table').find(':checked').each(function(){ + if (this.parentElement.parentElement.id !== '') { + dataset_ids.push(this.parentElement.parentElement.id); + } + }); + var progress_bar_tmpl = this.templateProgressBar(); + $(this.modal.elMain).find('.modal-body').html(progress_bar_tmpl({ history_name : history_name })); + + // init the progress bar + var progressStep = 100 / dataset_ids.length; + this.initProgress(progressStep); + + // prepare the dataset objects to be imported + var datasets_to_import = []; + for (var i = dataset_ids.length - 1; i >= 0; i--) { + library_dataset_id = dataset_ids[i]; + var historyItem = new mod_library_model.HistoryItem(); + var self = this; + historyItem.url = historyItem.urlRoot + history_id + '/contents'; + historyItem.content = library_dataset_id; + historyItem.source = 'library'; + datasets_to_import.push(historyItem); + } + // call the recursive function to call ajax one after each other (request FIFO queue) + this.chainCall(datasets_to_import); + }, + + chainCall: function(history_item_set){ + var self = this; + var popped_item = history_item_set.pop(); + if (typeof popped_item === "undefined") { + mod_toastr.success('All datasets imported'); + this.modal.hide(); + return; + } + var promise = $.when(popped_item.save({content: popped_item.content, source: popped_item.source})).done(function(a1){ + self.updateProgress(); + self.chainCall(history_item_set); + }); + }, + + initProgress: function(progressStep){ + this.progress = 0; + this.progressStep = progressStep; + }, + + updateProgress: function(){ + this.progress += this.progressStep; + $('.progress-bar-import').width(Math.round(this.progress) + '%'); + txt_representation = Math.round(this.progress) + '% Complete'; + $('.completion_span').text(txt_representation); + }, + + // download selected datasets + download : function(folder_id, format){ + var dataset_ids = []; + $('#folder_table').find(':checked').each(function(){ + if (this.parentElement.parentElement.id !== '') { + dataset_ids.push(this.parentElement.parentElement.id); + } + }); + + var url = '/api/libraries/datasets/download/' + format; + var data = {'ldda_ids' : dataset_ids}; + this.processDownload(url, data, 'get'); + }, + + // create hidden form and submit through POST to initialize download + processDownload: function(url, data, method){ + //url and data options required + if( url && data ){ + //data can be string of parameters or array/object + data = typeof data == 'string' ? data : $.param(data); + //split params into form inputs + var inputs = ''; + $.each(data.split('&'), function(){ + var pair = this.split('='); + inputs+=''; + }); + //send request + $('
'+inputs+'
') + .appendTo('body').submit().remove(); + + mod_toastr.info('Your download will begin soon'); + } + }, + + templateToolBar: function(){ + tmpl_array = []; + + // CONTAINER + tmpl_array.push('
'); + tmpl_array.push('

Data Libraries Beta Test. This is work in progress. Please report problems & ideas via email and Trello.

'); + // TOOLBAR + tmpl_array.push('
'); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push(' '); + tmpl_array.push('
'); + tmpl_array.push('
'); + // library items will append here + tmpl_array.push('
'); + tmpl_array.push('
'); + + return _.template(tmpl_array.join('')); + }, + + templateNewFolderInModal: function(){ + tmpl_array = []; + + tmpl_array.push('
'); + tmpl_array.push('
'); + tmpl_array.push(''); + tmpl_array.push(''); + tmpl_array.push('
'); + tmpl_array.push('
'); + + return _.template(tmpl_array.join('')); + }, + + + templateBulkImportInModal : function(){ + var tmpl_array = []; + + tmpl_array.push(''); + tmpl_array.push('Select history: '); + tmpl_array.push(''); + tmpl_array.push(''); + + return _.template(tmpl_array.join('')); + }, + + templateProgressBar : function (){ + var tmpl_array = []; + + tmpl_array.push('
'); + tmpl_array.push('Importing selected datasets to history <%= _.escape(history_name) %>'); + tmpl_array.push('
'); + tmpl_array.push('
'); + tmpl_array.push('
'); + tmpl_array.push(' 0% Complete'); + tmpl_array.push('
'); + tmpl_array.push('
'); + tmpl_array.push(''); + + return _.template(tmpl_array.join('')); + } +}); + +return { + FolderToolbarView: FolderToolbarView +}; + +}); diff --git a/static/scripts/mvc/library/library-librarylist-view.js b/static/scripts/mvc/library/library-librarylist-view.js index f183fbd00df..5bea6fe4228 100644 --- a/static/scripts/mvc/library/library-librarylist-view.js +++ b/static/scripts/mvc/library/library-librarylist-view.js @@ -1,14 +1,14 @@ // dependencies define([ "galaxy.masthead", - "mvc/base-mvc", + "mvc/base-mvc", "utils/utils", "libs/toastr", "mvc/library/library-model", - "mvc/library/library-libraryrow-view"], + "mvc/library/library-libraryrow-view"], function(mod_masthead, - mod_baseMVC, - mod_utils, + mod_baseMVC, + mod_utils, mod_toastr, mod_library_model, mod_library_libraryrow_view) { @@ -29,7 +29,8 @@ var LibraryListView = Backbone.View.extend({ rowViews: {}, // initialize - initialize : function(){ + initialize : function(options){ + this.options = _.defaults(this.options || {}, options); var viewContext = this; this.rowViews = {}; @@ -43,7 +44,7 @@ var LibraryListView = Backbone.View.extend({ error: function(model, response){ mod_toastr.error('An error occured. Please try again.'); } - }) + }); }, /** Renders the libraries table either from the object's own collection, @@ -52,9 +53,8 @@ var LibraryListView = Backbone.View.extend({ render: function (options) { var template = this.templateLibraryList(); var libraries_to_render = null; - var include_deleted = true; var include_deleted = Galaxy.libraries.preferences.get('with_deleted'); - var models = null + var models = null; if (typeof options !== 'undefined'){ include_deleted = typeof options.with_deleted !== 'undefined' ? options.with_deleted : false; models = typeof options.models !== 'undefined' ? options.models : null; @@ -64,7 +64,7 @@ var LibraryListView = Backbone.View.extend({ if (include_deleted){ // show all the libraries libraries_to_render = this.collection.models; } else{ // show only undeleted libraries - libraries_to_render = this.collection.where({deleted: false});; + libraries_to_render = this.collection.where({deleted: false}); } } else if (models !== null){ libraries_to_render = models; @@ -74,7 +74,9 @@ var LibraryListView = Backbone.View.extend({ this.$el.html(template({length: libraries_to_render.length, order: Galaxy.libraries.preferences.get('sort_order') })); - this.renderRows(libraries_to_render); + if (libraries_to_render.length > 0){ + this.renderRows(libraries_to_render); + } // initialize the library tooltips $("#center [data-toggle]").tooltip(); // modification of upper DOM element to show scrollbars due to the #center element inheritance @@ -92,9 +94,9 @@ var LibraryListView = Backbone.View.extend({ var rowView = new mod_library_libraryrow_view.LibraryRowView(library); this.$el.find('#library_list_body').append(rowView.el); // save new rowView to cache - this.rowViews[library.get('id')] = rowView; + this.rowViews[library.get('id')] = rowView; } - }; + } }, sort_clicked : function(){ @@ -115,17 +117,17 @@ var LibraryListView = Backbone.View.extend({ if (order === 'asc'){ // this.collection.sort_order = 'asc'; this.collection.comparator = function(libraryA, libraryB){ - if (libraryA.get('name').toLowerCase() > libraryB.get('name').toLowerCase()) return 1; // after - if (libraryB.get('name').toLowerCase() > libraryA.get('name').toLowerCase()) return -1; // before + if (libraryA.get('name').toLowerCase() > libraryB.get('name').toLowerCase()) {return 1;} // after + if (libraryB.get('name').toLowerCase() > libraryA.get('name').toLowerCase()) {return -1;} // before return 0; // equal - } + }; } else if (order === 'desc'){ // this.collection.sort_order = 'desc'; this.collection.comparator = function(libraryA, libraryB){ - if (libraryA.get('name').toLowerCase() > libraryB.get('name').toLowerCase()) return -1; // before - if (libraryB.get('name').toLowerCase() > libraryA.get('name').toLowerCase()) return 1; // after + if (libraryA.get('name').toLowerCase() > libraryB.get('name').toLowerCase()) {return -1;} // before + if (libraryB.get('name').toLowerCase() > libraryA.get('name').toLowerCase()) {return 1;} // after return 0; // equal - } + }; } this.collection.sort(); } @@ -140,7 +142,7 @@ var LibraryListView = Backbone.View.extend({ tmpl_array.push('
'); tmpl_array.push('<% if(length === 0) { %>'); - tmpl_array.push("
I see no libraries. Why don't you create one?
"); + tmpl_array.push('
There are no libraries visible to you. If you expected some to show up please consult the library security wikipage.
'); tmpl_array.push('<% } else{ %>'); tmpl_array.push(''); tmpl_array.push(' '); @@ -175,7 +177,7 @@ var LibraryListView = Backbone.View.extend({ redirectToHome: function(){ window.location = '../'; - }, + }, redirectToLogin: function(){ window.location = '/user/login'; }, @@ -193,7 +195,7 @@ var LibraryListView = Backbone.View.extend({ title : 'Create New Library', body : this.templateNewLibraryInModal(), buttons : { - 'Create' : function() {self.create_new_library_event()}, + 'Create' : function() {self.create_new_library_event();}, 'Close' : function() {self.modal.hide();} } }); @@ -245,7 +247,6 @@ var LibraryListView = Backbone.View.extend({ } }); -// return return { LibraryListView: LibraryListView }; diff --git a/static/scripts/mvc/library/library-libraryrow-view.js b/static/scripts/mvc/library/library-libraryrow-view.js index b7deca3a5aa..3184f6e4ca3 100644 --- a/static/scripts/mvc/library/library-libraryrow-view.js +++ b/static/scripts/mvc/library/library-libraryrow-view.js @@ -1,11 +1,11 @@ // dependencies define([ - "galaxy.masthead", + "galaxy.masthead", "utils/utils", "libs/toastr", - "mvc/library/library-model"], -function(mod_masthead, - mod_utils, + "mvc/library/library-model"], +function(mod_masthead, + mod_utils, mod_toastr, mod_library_model) { @@ -39,7 +39,7 @@ var LibraryRowView = Backbone.View.extend({ render: function(library){ if (typeof library === 'undefined'){ - var library = Galaxy.libraries.libraryListView.collection.get(this.$el.data('id')); + library = Galaxy.libraries.libraryListView.collection.get(this.$el.data('id')); } this.prepareButtons(library); var tmpl = this.templateRow(); @@ -51,7 +51,7 @@ var LibraryRowView = Backbone.View.extend({ repaint: function(library){ /* need to hide manually because of the element removal in setElement invoked in render() */ - $(".tooltip").hide(); + $(".tooltip").hide(); /* we need to store the old element to be able to replace it with new one */ var old_element = this.$el; @@ -83,13 +83,13 @@ var LibraryRowView = Backbone.View.extend({ vis_config.undelete_library_btn = false; if (library.get('can_user_add') === true){ vis_config.upload_library_btn = true; - } + } if (library.get('can_user_modify') === true){ vis_config.edit_library_btn = true; - } + } if (library.get('can_user_manage') === true){ vis_config.permission_library_btn = true; - } + } } } else if (this.edit_mode === true){ vis_config.upload_library_btn = false; @@ -136,7 +136,7 @@ var LibraryRowView = Backbone.View.extend({ is_changed = true; } else{ mod_toastr.warning('Library name has to be at least 3 characters long'); - return + return; } } @@ -183,7 +183,7 @@ var LibraryRowView = Backbone.View.extend({ Galaxy.libraries.libraryListView.collection.add(library); row_view.edit_mode = false; if (Galaxy.libraries.preferences.get('with_deleted') === false){ - $(".tooltip").hide(); + $('.tooltip').hide(); row_view.$el.remove(); } else if (Galaxy.libraries.preferences.get('with_deleted') === true){ row_view.repaint(library); @@ -247,12 +247,11 @@ var LibraryRowView = Backbone.View.extend({ tmpl_array.push(' '); tmpl_array.push(' '); - return _.template(tmpl_array.join('')); + return _.template(tmpl_array.join('')); } }); - // return return { LibraryRowView: LibraryRowView }; diff --git a/static/scripts/mvc/library/library-librarytoolbar-view.js b/static/scripts/mvc/library/library-librarytoolbar-view.js index f713575e8ca..bc35c73c054 100644 --- a/static/scripts/mvc/library/library-librarytoolbar-view.js +++ b/static/scripts/mvc/library/library-librarytoolbar-view.js @@ -1,18 +1,18 @@ // dependencies define([ - "galaxy.masthead", + "galaxy.masthead", "utils/utils", "libs/toastr", - "mvc/library/library-model"], -function(mod_masthead, - mod_utils, + "mvc/library/library-model"], +function(mod_masthead, + mod_utils, mod_toastr, mod_library_model) { -var ToolbarView = Backbone.View.extend({ +var LibraryToolbarView = Backbone.View.extend({ el: '#center', - events: { + events: { 'click #create_new_library_btn' : 'delegate_modal', 'click #include_deleted_chk' : 'check_include_deleted' }, @@ -23,14 +23,16 @@ var ToolbarView = Backbone.View.extend({ render: function(){ var toolbar_template = this.templateToolBar(); - this.$el.html(toolbar_template({admin_user: Galaxy.currUser.isAdmin(), anon_user: Galaxy.currUser.isAnonymous()})) + var is_admin = Galaxy.currUser.isAdmin(); + var is_anonym = Galaxy.currUser.isAnonymous(); + this.$el.html(toolbar_template({admin_user: is_admin, anon_user: is_anonym})); if (Galaxy.currUser.isAdmin() === true){ this.$el.find('#include_deleted_chk')[0].checked = Galaxy.libraries.preferences.get('with_deleted'); } }, delegate_modal: function(event){ - // probably should refactor to have this functionality in this view, not in the library view + // probably should refactor to have this functionality in this view, not in the library list view Galaxy.libraries.libraryListView.show_library_modal(event); }, @@ -48,7 +50,7 @@ var ToolbarView = Backbone.View.extend({ templateToolBar: function(){ tmpl_array = []; - tmpl_array.push('
'); + tmpl_array.push('
'); // TOOLBAR tmpl_array.push('
'); tmpl_array.push('

Data Libraries Beta Test. This is work in progress. Please report problems & ideas via email and Trello.

'); @@ -60,16 +62,16 @@ var ToolbarView = Backbone.View.extend({ tmpl_array.push(' <% } %>'); tmpl_array.push('
'); tmpl_array.push('
'); + // table with libraries will append here tmpl_array.push('
'); tmpl_array.push('
'); return _.template(tmpl_array.join('')); } -}) +}); -// return return { - ToolbarView: ToolbarView + LibraryToolbarView: LibraryToolbarView }; }); diff --git a/static/scripts/mvc/library/library-model.js b/static/scripts/mvc/library/library-model.js index d159bc4409e..6942ae53753 100644 --- a/static/scripts/mvc/library/library-model.js +++ b/static/scripts/mvc/library/library-model.js @@ -66,16 +66,14 @@ define([], function() { var FolderContainer = Backbone.Model.extend({ defaults : { folder : new Folder(), - full_path : "unknown", urlRoot : "/api/folders/", id : "unknown" }, parse : function(obj) { - this.full_path = obj[0].full_path; - // response is not a simple array, it contains metadata - // this will update the inner collection - this.get("folder").reset(obj[1].folder_contents); - return obj; + // response is not a simple array, it contains metadata + // this will update the inner collection + this.get("folder").reset(obj.folder_contents); + return obj; } }); diff --git a/static/scripts/mvc/tools.js b/static/scripts/mvc/tools.js index a1156b2bb31..12e2e6c7515 100644 --- a/static/scripts/mvc/tools.js +++ b/static/scripts/mvc/tools.js @@ -42,7 +42,7 @@ var ToolParameter = Backbone.Model.extend({ num_samples: 5 }, - initialize: function() { + initialize: function(options) { this.attributes.html = unescape(this.attributes.html); }, @@ -124,6 +124,8 @@ var Tool = Backbone.Model.extend({ outputs: [] }, + urlRoot: galaxy_config.root + 'api/tools', + initialize: function(options) { // Set parameters. @@ -133,7 +135,16 @@ var Tool = Backbone.Model.extend({ }))); }, - urlRoot: galaxy_config.root + 'api/tools', + /** + * + */ + toJSON: function() { + var rval = Backbone.Model.prototype.toJSON.call(this); + + // Convert inputs to JSON manually. + rval.inputs = this.get('inputs').map(function(i) { return i.toJSON(); }); + return rval; + }, /** * Removes inputs of a particular type; this is useful because not all inputs can be handled by diff --git a/static/scripts/packed/galaxy.library.js b/static/scripts/packed/galaxy.library.js index 1e2cf49375f..592aecc523d 100644 --- a/static/scripts/packed/galaxy.library.js +++ b/static/scripts/packed/galaxy.library.js @@ -1 +1 @@ -var library_router=null;define(["galaxy.masthead","utils/utils","libs/toastr","mvc/base-mvc","mvc/library/library-model","mvc/library/library-folderlist-view","mvc/library/library-librarylist-view","mvc/library/library-librarytoolbar-view"],function(e,c,g,j,h,a,f,d){var k=Backbone.Router.extend({routes:{"":"libraries","sort/:sort_by/:order":"sort_libraries","folders/:id":"folder_content","folders/:folder_id/download/:format":"download"}});var i=j.SessionStorageModel.extend({defaults:{with_deleted:false,sort_order:"asc",sort_by:"name"}});var b=Backbone.View.extend({toolbarView:null,libraryListView:null,library_router:null,folderContentView:null,initialize:function(){Galaxy.libraries=this;this.preferences=new i({id:"global-lib-prefs"});this.library_router=new k();this.library_router.on("route:libraries",function(){Galaxy.libraries.toolbarView=new d.ToolbarView();Galaxy.libraries.libraryListView=new f.LibraryListView()});this.library_router.on("route:folder_content",function(l){if(!Galaxy.libraries.folderContentView){Galaxy.libraries.folderContentView=new a.FolderContentView()}Galaxy.libraries.folderContentView.render({id:l})});this.library_router.on("route:download",function(l,m){if($("#center").find(":checked").length===0){Galaxy.libraries.library_router.navigate("folders/"+l,{trigger:true,replace:true})}else{Galaxy.libraries.folderContentView.download(l,m);Galaxy.libraries.library_router.navigate("folders/"+l,{trigger:false,replace:true})}});Backbone.history.start({pushState:false})}});return{GalaxyApp:b}}); \ No newline at end of file +define(["galaxy.masthead","utils/utils","libs/toastr","mvc/base-mvc","mvc/library/library-model","mvc/library/library-folderlist-view","mvc/library/library-librarylist-view","mvc/library/library-librarytoolbar-view","mvc/library/library-foldertoolbar-view"],function(e,c,g,k,h,a,f,d,i){var l=Backbone.Router.extend({routes:{"":"libraries","sort/:sort_by/:order":"sort_libraries","folders/:id":"folder_content","folders/:folder_id/download/:format":"download"}});var j=k.SessionStorageModel.extend({defaults:{with_deleted:false,sort_order:"asc",sort_by:"name"}});var b=Backbone.View.extend({libraryToolbarView:null,libraryListView:null,library_router:null,folderToolbarView:null,folderListView:null,initialize:function(){Galaxy.libraries=this;this.preferences=new j({id:"global-lib-prefs"});this.library_router=new l();this.library_router.on("route:libraries",function(){Galaxy.libraries.libraryToolbarView=new d.LibraryToolbarView();Galaxy.libraries.libraryListView=new f.LibraryListView()});this.library_router.on("route:folder_content",function(m){Galaxy.libraries.folderToolbarView=new i.FolderToolbarView({id:m});Galaxy.libraries.folderListView=new a.FolderListView({id:m})});this.library_router.on("route:download",function(m,n){if($("#center").find(":checked").length===0){g.info("You have to select some datasets to download");Galaxy.libraries.library_router.navigate("folders/"+m,{trigger:true,replace:true})}else{Galaxy.libraries.folderToolbarView.download(m,n);Galaxy.libraries.library_router.navigate("folders/"+m,{trigger:false,replace:true})}});Backbone.history.start({pushState:false})}});return{GalaxyApp:b}}); \ No newline at end of file diff --git a/static/scripts/packed/galaxy.workflow_editor.canvas.js b/static/scripts/packed/galaxy.workflow_editor.canvas.js index a15d9116073..2536ea4b2a6 100644 --- a/static/scripts/packed/galaxy.workflow_editor.canvas.js +++ b/static/scripts/packed/galaxy.workflow_editor.canvas.js @@ -1 +1 @@ -function Terminal(a){this.element=a;this.connectors=[]}$.extend(Terminal.prototype,{connect:function(a){this.connectors.push(a);if(this.node){this.node.changed()}},disconnect:function(a){this.connectors.splice($.inArray(a,this.connectors),1);if(this.node){this.node.changed()}},redraw:function(){$.each(this.connectors,function(a,b){b.redraw()})},destroy:function(){$.each(this.connectors.slice(),function(a,b){b.destroy()})}});function OutputTerminal(a,b){Terminal.call(this,a);this.datatypes=b}OutputTerminal.prototype=new Terminal();function InputTerminal(b,c,a){Terminal.call(this,b);this.datatypes=c;this.multiple=a}InputTerminal.prototype=new Terminal();$.extend(InputTerminal.prototype,{can_accept:function(a){if(this.connectors.length<1||this.multiple){for(var c in this.datatypes){var f=new Array();f=f.concat(a.datatypes);if(a.node.post_job_actions){for(var d in a.node.post_job_actions){var g=a.node.post_job_actions[d];if(g.action_type=="ChangeDatatypeAction"&&(g.output_name==""||g.output_name==a.name)&&g.action_arguments){f.push(g.action_arguments.newtype)}}}for(var b in f){if(f[b]=="input"||issubtype(f[b],this.datatypes[c])){return true}}}}return false}});function Connector(b,a){this.canvas=null;this.dragging=false;this.inner_color="#FFFFFF";this.outer_color="#D8B365";if(b&&a){this.connect(b,a)}}$.extend(Connector.prototype,{connect:function(b,a){this.handle1=b;if(this.handle1){this.handle1.connect(this)}this.handle2=a;if(this.handle2){this.handle2.connect(this)}},destroy:function(){if(this.handle1){this.handle1.disconnect(this)}if(this.handle2){this.handle2.disconnect(this)}$(this.canvas).remove()},redraw:function(){var d=$("#canvas-container");if(!this.canvas){this.canvas=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(this.canvas)}d.append($(this.canvas));if(this.dragging){this.canvas.style.zIndex="300"}}var n=function(c){return $(c).offset().left-d.offset().left};var i=function(c){return $(c).offset().top-d.offset().top};if(!this.handle1||!this.handle2){return}var h=n(this.handle1.element)+5;var g=i(this.handle1.element)+5;var p=n(this.handle2.element)+5;var m=i(this.handle2.element)+5;var f=100;var k=Math.min(h,p);var a=Math.max(h,p);var j=Math.min(g,m);var t=Math.max(g,m);var b=Math.min(Math.max(Math.abs(t-j)/2,100),300);var o=k-f;var s=j-f;var q=a-k+2*f;var l=t-j+2*f;this.canvas.style.left=o+"px";this.canvas.style.top=s+"px";this.canvas.setAttribute("width",q);this.canvas.setAttribute("height",l);h-=o;g-=s;p-=o;m-=s;var r=this.canvas.getContext("2d");r.lineCap="round";r.strokeStyle=this.outer_color;r.lineWidth=7;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke();r.strokeStyle=this.inner_color;r.lineWidth=5;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke()}});function Node(a){this.element=a;this.input_terminals={};this.output_terminals={};this.tool_errors={}}$.extend(Node.prototype,{new_input_terminal:function(a){var b=$("
");this.enable_input_terminal(b,a.name,a.extensions,a.multiple);return b},enable_input_terminal:function(f,b,c,a){var d=this;$(f).each(function(){var g=this.terminal=new InputTerminal(this,c,a);g.node=d;g.name=b;$(this).bind("dropinit",function(h,i){return $(i.drag).hasClass("output-terminal")&&g.can_accept(i.drag.terminal)}).bind("dropstart",function(h,i){if(i.proxy.terminal){i.proxy.terminal.connectors[0].inner_color="#BBFFBB"}}).bind("dropend",function(h,i){if(i.proxy.terminal){i.proxy.terminal.connectors[0].inner_color="#FFFFFF"}}).bind("drop",function(h,i){(new Connector(i.drag.terminal,g)).redraw()}).bind("hover",function(){if(g.connectors.length>0){var h=$("
").css({display:"none"}).appendTo("body").append($("
").append($("
").addClass("fa-icon-button fa fa-times").click(function(){$.each(g.connectors,function(j,i){if(i){i.destroy()}});h.remove()}))).bind("mouseleave",function(){$(this).remove()});h.css({top:$(this).offset().top-2,left:$(this).offset().left-h.width(),"padding-right":$(this).width()}).show()}});d.input_terminals[b]=g})},enable_output_terminal:function(d,a,b){var c=this;$(d).each(function(){var g=this;var f=this.terminal=new OutputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dragstart",function(j,k){$(k.available).addClass("input-terminal-active");workflow.check_changes_in_active_form();var i=$('
').appendTo("#canvas-container").get(0);i.terminal=new OutputTerminal(i);var l=new Connector();l.dragging=true;l.connect(this.terminal,i.terminal);return i}).bind("drag",function(i,j){var h=function(){var l=$(j.proxy).offsetParent().offset(),k=j.offsetX-l.left,m=j.offsetY-l.top;$(j.proxy).css({left:k,top:m});j.proxy.terminal.redraw();canvas_manager.update_viewport_overlay()};h();$("#canvas-container").get(0).scroll_panel.test(i,h)}).bind("dragend",function(h,i){i.proxy.terminal.connectors[0].destroy();$(i.proxy).remove();$(i.available).removeClass("input-terminal-active");$("#canvas-container").get(0).scroll_panel.stop()});c.output_terminals[a]=f})},redraw:function(){$.each(this.input_terminals,function(a,b){b.redraw()});$.each(this.output_terminals,function(a,b){b.redraw()})},destroy:function(){$.each(this.input_terminals,function(a,b){b.destroy()});$.each(this.output_terminals,function(a,b){b.destroy()});workflow.remove_node(this);$(this.element).remove()},make_active:function(){$(this.element).addClass("toolForm-active")},make_inactive:function(){var a=this.element.get(0);(function(b){b.removeChild(a);b.appendChild(a)})(a.parentNode);$(a).removeClass("toolForm-active")},init_field_data:function(h){var g=this.element;if(h.type){this.type=h.type}this.name=h.name;this.form_html=h.form_html;this.tool_state=h.tool_state;this.tool_errors=h.tool_errors;this.tooltip=h.tooltip?h.tooltip:"";this.annotation=h.annotation;this.post_job_actions=h.post_job_actions?h.post_job_actions:{};this.workflow_outputs=h.workflow_outputs?h.workflow_outputs:[];if(this.tool_errors){g.addClass("tool-node-error")}else{g.removeClass("tool-node-error")}var d=this;var c=Math.max(150,g.width());var a=g.find(".toolFormBody");a.find("div").remove();var i=$("
").appendTo(a);$.each(h.data_inputs,function(k,f){var j=d.new_input_terminal(f);var b=$("
"+f.label+"
");b.css({position:"absolute",left:-1000,top:-1000,display:"none"});$("body").append(b);c=Math.max(c,b.outerWidth());b.css({position:"",left:"",top:"",display:""});b.remove();i.append(b.prepend(j))});if((h.data_inputs.length>0)&&(h.data_outputs.length>0)){a.append($("
"))}$.each(h.data_outputs,function(k,b){var j=$("
");d.enable_output_terminal(j,b.name,b.extensions);var f=b.name;if(b.extensions.indexOf("input")<0){f=f+" ("+b.extensions.join(", ")+")"}var m=$("
"+f+"
");if(d.type=="tool"){var l=$("
").css({display:"none"}).append($("
").append($("").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png").click(function(){if($.inArray(b.name,d.workflow_outputs)!=-1){d.workflow_outputs.splice($.inArray(b.name,d.workflow_outputs),1);l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{d.workflow_outputs.push(b.name);l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}workflow.has_changes=true;canvas_manager.draw_overview()}))).tooltip({delay:500,title:"Mark dataset as a workflow output. All unmarked datasets will be hidden."});l.css({top:"50%",margin:"-8px 0px 0px 0px",right:8});l.show();m.append(l);if($.inArray(b.name,d.workflow_outputs)===-1){l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}m.hover(function(){l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-yellow.png")},function(){if($.inArray(b.name,d.workflow_outputs)===-1){l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}})}m.css({position:"absolute",left:-1000,top:-1000,display:"none"});$("body").append(m);c=Math.max(c,m.outerWidth()+17);m.css({position:"",left:"",top:"",display:""});m.detach();a.append(m.append(j))});g.css("width",Math.min(250,Math.max(g.width(),c)));workflow.node_changed(this)},update_field_data:function(f){var c=$(this.element),d=this;this.tool_state=f.tool_state;this.form_html=f.form_html;this.tool_errors=f.tool_errors;this.annotation=f.annotation;var g=$.parseJSON(f.post_job_actions);this.post_job_actions=g?g:{};if(this.tool_errors){c.addClass("tool-node-error")}else{c.removeClass("tool-node-error")}var h=c.find("div.inputs");var b=$("
");var a=h.find("div.input-data-row");$.each(f.data_inputs,function(l,j){var k=d.new_input_terminal(j);h.find("div[name='"+j.name+"']").each(function(){$(this).find(".input-terminal").each(function(){var i=this.terminal.connectors[0];if(i){k[0].terminal.connectors[0]=i;i.handle2=k[0].terminal}});$(this).remove()});b.append($("
"+j.label+"
").prepend(k))});h.replaceWith(b);h.find("div.input-data-row > .terminal").each(function(){this.terminal.destroy()});this.changed();this.redraw()},error:function(d){var a=$(this.element).find(".toolFormBody");a.find("div").remove();var c="
"+d+"
";this.form_html=c;a.html(c);workflow.node_changed(this)},changed:function(){workflow.node_changed(this)}});function Workflow(a){this.canvas_container=a;this.id_counter=0;this.nodes={};this.name=null;this.has_changes=false;this.active_form_has_changes=false}$.extend(Workflow.prototype,{add_node:function(a){a.id=this.id_counter;a.element.attr("id","wf-node-step-"+a.id);this.id_counter++;this.nodes[a.id]=a;this.has_changes=true;a.workflow=this},remove_node:function(a){if(this.active_node==a){this.clear_active_node()}delete this.nodes[a.id];this.has_changes=true},remove_all:function(){wf=this;$.each(this.nodes,function(b,a){a.destroy();wf.remove_node(a)})},rectify_workflow_outputs:function(){var b=false;var a=false;$.each(this.nodes,function(c,d){if(d.workflow_outputs&&d.workflow_outputs.length>0){b=true}$.each(d.post_job_actions,function(g,f){if(f.action_type==="HideDatasetAction"){a=true}})});if(b!==false||a!==false){$.each(this.nodes,function(c,g){if(g.type==="tool"){var f=false;if(g.post_job_actions==null){g.post_job_actions={};f=true}var d=[];$.each(g.post_job_actions,function(i,h){if(h.action_type=="HideDatasetAction"){d.push(i)}});if(d.length>0){$.each(d,function(h,j){f=true;delete g.post_job_actions[j]})}if(b){$.each(g.output_terminals,function(i,j){var h=true;$.each(g.workflow_outputs,function(l,m){if(j.name===m){h=false}});if(h===true){f=true;var k={action_type:"HideDatasetAction",output_name:j.name,action_arguments:{}};g.post_job_actions["HideDatasetAction"+j.name]=null;g.post_job_actions["HideDatasetAction"+j.name]=k}})}if(workflow.active_node==g&&f===true){workflow.reload_active_node()}}})}},to_simple:function(){var a={};$.each(this.nodes,function(c,f){var g={};$.each(f.input_terminals,function(i,j){g[j.name]=null;var h=[];$.each(j.connectors,function(k,l){h[k]={id:l.handle1.node.id,output_name:l.handle1.name};g[j.name]=h})});var b={};if(f.post_job_actions){$.each(f.post_job_actions,function(j,h){var k={action_type:h.action_type,output_name:h.output_name,action_arguments:h.action_arguments};b[h.action_type+h.output_name]=null;b[h.action_type+h.output_name]=k})}if(!f.workflow_outputs){f.workflow_outputs=[]}var d={id:f.id,type:f.type,tool_id:f.tool_id,tool_state:f.tool_state,tool_errors:f.tool_errors,input_connections:g,position:$(f.element).position(),annotation:f.annotation,post_job_actions:f.post_job_actions,workflow_outputs:f.workflow_outputs};a[f.id]=d});return{steps:a}},from_simple:function(b){wf=this;var c=0;wf.name=b.name;var a=false;$.each(b.steps,function(g,f){var d=prebuild_node(f.type,f.name,f.tool_id);d.init_field_data(f);if(f.position){d.element.css({top:f.position.top,left:f.position.left})}d.id=f.id;wf.nodes[d.id]=d;c=Math.max(c,parseInt(g));if(!a&&d.type==="tool"){if(d.workflow_outputs.length>0){a=true}else{$.each(d.post_job_actions,function(i,h){if(h.action_type==="HideDatasetAction"){a=true}})}}});wf.id_counter=c+1;$.each(b.steps,function(g,f){var d=wf.nodes[g];$.each(f.input_connections,function(i,h){if(h){if(!$.isArray(h)){h=[h]}$.each(h,function(k,j){var m=wf.nodes[j.id];var n=new Connector();n.connect(m.output_terminals[j.output_name],d.input_terminals[i]);n.redraw()})}});if(a&&d.type==="tool"){$.each(d.output_terminals,function(h,i){if(d.post_job_actions["HideDatasetAction"+i.name]===undefined){d.workflow_outputs.push(i.name);callout=$(d.element).find(".callout."+i.name);callout.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png");workflow.has_changes=true}})}})},check_changes_in_active_form:function(){if(this.active_form_has_changes){this.has_changes=true;$("#right-content").find("form").submit();this.active_form_has_changes=false}},reload_active_node:function(){if(this.active_node){var a=this.active_node;this.clear_active_node();this.activate_node(a)}},clear_active_node:function(){if(this.active_node){this.active_node.make_inactive();this.active_node=null}parent.show_form_for_tool("
No node selected
")},activate_node:function(a){if(this.active_node!=a){this.check_changes_in_active_form();this.clear_active_node();parent.show_form_for_tool(a.form_html+a.tooltip,a);a.make_active();this.active_node=a}},node_changed:function(a){this.has_changes=true;if(this.active_node==a){this.check_changes_in_active_form();parent.show_form_for_tool(a.form_html+a.tooltip,a)}},layout:function(){this.check_changes_in_active_form();this.has_changes=true;var i={};var b={};$.each(this.nodes,function(l,k){if(i[l]===undefined){i[l]=0}if(b[l]===undefined){b[l]=[]}});$.each(this.nodes,function(l,k){$.each(k.input_terminals,function(m,n){$.each(n.connectors,function(p,q){var o=q.handle1.node;i[k.id]+=1;b[o.id].push(k.id)})})});node_ids_by_level=[];while(true){level_parents=[];for(var a in i){if(i[a]==0){level_parents.push(a)}}if(level_parents.length==0){break}node_ids_by_level.push(level_parents);for(var f in level_parents){var j=level_parents[f];delete i[j];for(var g in b[j]){i[b[j][g]]-=1}}}if(i.length){return}var d=this.nodes;var h=80;v_pad=30;var c=h;$.each(node_ids_by_level,function(k,l){l.sort(function(p,o){return $(d[p].element).position().top-$(d[o].element).position().top});var m=0;var n=v_pad;$.each(l,function(o,r){var q=d[r];var p=$(q.element);$(p).css({top:n,left:c});m=Math.max(m,$(p).width());n+=$(p).height()+v_pad});c+=m+h});$.each(d,function(k,l){l.redraw()})},bounds_for_all_nodes:function(){var d=Infinity,b=-Infinity,c=Infinity,a=-Infinity,f;$.each(this.nodes,function(h,g){e=$(g.element);f=e.position();d=Math.min(d,f.left);b=Math.max(b,f.left+e.width());c=Math.min(c,f.top);a=Math.max(a,f.top+e.width())});return{xmin:d,xmax:b,ymin:c,ymax:a}},fit_canvas_to_nodes:function(){var a=this.bounds_for_all_nodes();var f=this.canvas_container.position();var i=this.canvas_container.parent();var d=fix_delta(a.xmin,100);var h=fix_delta(a.ymin,100);d=Math.max(d,f.left);h=Math.max(h,f.top);var c=f.left-d;var g=f.top-h;var b=round_up(a.xmax+100,100)+d;var j=round_up(a.ymax+100,100)+h;b=Math.max(b,-c+i.width());j=Math.max(j,-g+i.height());this.canvas_container.css({left:c,top:g,width:b,height:j});this.canvas_container.children().each(function(){var k=$(this).position();$(this).css("left",k.left+d);$(this).css("top",k.top+h)})}});function fix_delta(a,b){if(a3*b){new_pos=(Math.ceil(((a%b))/b)+1)*b;return(-(a-new_pos))}return 0}function round_up(a,b){return Math.ceil(a/b)*b}function prebuild_node(l,j,r){var i=$("
");var g=new Node(i);g.type=l;if(l=="tool"){g.tool_id=r}var n=$("
"+j+"
");i.append(n);i.css("left",$(window).scrollLeft()+20);i.css("top",$(window).scrollTop()+20);var m=$("
");var h="
loading tool info...
";m.append(h);g.form_html=h;i.append(m);var k=$("
");k.append($("
").addClass("fa-icon-button fa fa-times").click(function(b){g.destroy()}));i.appendTo("#canvas-container");var d=$("#canvas-container").position();var c=$("#canvas-container").parent();var a=i.width();var q=i.height();i.css({left:(-d.left)+(c.width()/2)-(a/2),top:(-d.top)+(c.height()/2)-(q/2)});k.prependTo(n);a+=(k.width()+10);i.css("width",a);$(i).bind("dragstart",function(){workflow.activate_node(g)}).bind("dragend",function(){workflow.node_changed(this);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview()}).bind("dragclickonly",function(){workflow.activate_node(g)}).bind("drag",function(o,p){var f=$(this).offsetParent().offset(),b=p.offsetX-f.left,s=p.offsetY-f.top;$(this).css({left:b,top:s});$(this).find(".terminal").each(function(){this.terminal.redraw()})});return g}var ext_to_type=null;var type_to_type=null;function issubtype(b,a){b=ext_to_type[b];a=ext_to_type[a];return(type_to_type[b])&&(a in type_to_type[b])}function populate_datatype_info(a){ext_to_type=a.ext_to_class_name;type_to_type=a.class_to_classes}function ScrollPanel(a){this.panel=a}$.extend(ScrollPanel.prototype,{test:function(v,d){clearTimeout(this.timeout);var k=v.pageX,j=v.pageY,l=$(this.panel),c=l.position(),b=l.width(),i=l.height(),w=l.parent(),s=w.width(),a=w.height(),r=w.offset(),p=r.left,m=r.top,A=p+w.width(),u=m+w.height(),B=-(b-(s/2)),z=-(i-(a/2)),g=(s/2),f=(a/2),h=false,q=5,o=23;if(k-qA){if(c.left>B){var n=Math.min(o,c.left-B);l.css("left",c.left-n);h=true}}else{if(j-qu){if(c.top>z){var n=Math.min(o,c.top-B);l.css("top",(c.top-n)+"px");h=true}}}}}if(h){d();var l=this;this.timeout=setTimeout(function(){l.test(v,d)},50)}},stop:function(b,a){clearTimeout(this.timeout)}});function CanvasManager(b,a){this.cv=b;this.cc=this.cv.find("#canvas-container");this.oc=a.find("#overview-canvas");this.ov=a.find("#overview-viewport");this.init_drag()}$.extend(CanvasManager.prototype,{init_drag:function(){var b=this;var a=function(f,g){f=Math.min(f,b.cv.width()/2);f=Math.max(f,-b.cc.width()+b.cv.width()/2);g=Math.min(g,b.cv.height()/2);g=Math.max(g,-b.cc.height()+b.cv.height()/2);b.cc.css({left:f,top:g});b.update_viewport_overlay()};this.cc.each(function(){this.scroll_panel=new ScrollPanel(this)});var d,c;this.cv.bind("dragstart",function(){var g=$(this).offset();var f=b.cc.position();c=f.top-g.top;d=f.left-g.left}).bind("drag",function(f,g){a(g.offsetX+d,g.offsetY+c)}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});this.ov.bind("drag",function(k,l){var h=b.cc.width(),n=b.cc.height(),m=b.oc.width(),j=b.oc.height(),f=$(this).offsetParent().offset(),i=l.offsetX-f.left,g=l.offsetY-f.top;a(-(i/m*h),-(g/j*n))}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});$("#overview-border").bind("drag",function(g,i){var j=$(this).offsetParent();var h=j.offset();var f=Math.max(j.width()-(i.offsetX-h.left),j.height()-(i.offsetY-h.top));$(this).css({width:f,height:f});b.draw_overview()});$("#overview-border div").bind("drag",function(){})},update_viewport_overlay:function(){var b=this.cc,f=this.cv,a=this.oc,c=this.ov,d=b.width(),j=b.height(),i=a.width(),g=a.height(),h=b.position();c.css({left:-(h.left/d*i),top:-(h.top/j*g),width:(f.width()/d*i)-2,height:(f.height()/j*g)-2})},draw_overview:function(){var j=$("#overview-canvas"),m=j.parent().parent().width(),i=j.get(0).getContext("2d"),d=$("#canvas-container").width(),l=$("#canvas-container").height();var g,a,k,f;var h=this.cv.width();var b=this.cv.height();if(d0){i.fillStyle="#E8A92D";i.strokeStyle="#E8A92D"}}i.fillRect(c,r,o,p);i.strokeRect(c,r,o,p)});this.update_viewport_overlay()}}); \ No newline at end of file +function Terminal(a){this.element=a;this.connectors=[]}$.extend(Terminal.prototype,{connect:function(a){this.connectors.push(a);if(this.node){this.node.changed()}},disconnect:function(a){this.connectors.splice($.inArray(a,this.connectors),1);if(this.node){this.node.changed()}},redraw:function(){$.each(this.connectors,function(a,b){b.redraw()})},destroy:function(){$.each(this.connectors.slice(),function(a,b){b.destroy()})}});function OutputTerminal(a,b){Terminal.call(this,a);this.datatypes=b}OutputTerminal.prototype=new Terminal();function InputTerminal(b,c,a){Terminal.call(this,b);this.datatypes=c;this.multiple=a}InputTerminal.prototype=new Terminal();$.extend(InputTerminal.prototype,{can_accept:function(a){if(this.connectors.length<1||this.multiple){for(var c in this.datatypes){var f=new Array();f=f.concat(a.datatypes);if(a.node.post_job_actions){for(var d in a.node.post_job_actions){var g=a.node.post_job_actions[d];if(g.action_type=="ChangeDatatypeAction"&&(g.output_name==""||g.output_name==a.name)&&g.action_arguments){f.push(g.action_arguments.newtype)}}}for(var b in f){if(f[b]=="input"||issubtype(f[b],this.datatypes[c])){return true}}}}return false}});function Connector(b,a){this.canvas=null;this.dragging=false;this.inner_color="#FFFFFF";this.outer_color="#D8B365";if(b&&a){this.connect(b,a)}}$.extend(Connector.prototype,{connect:function(b,a){this.handle1=b;if(this.handle1){this.handle1.connect(this)}this.handle2=a;if(this.handle2){this.handle2.connect(this)}},destroy:function(){if(this.handle1){this.handle1.disconnect(this)}if(this.handle2){this.handle2.disconnect(this)}$(this.canvas).remove()},redraw:function(){var d=$("#canvas-container");if(!this.canvas){this.canvas=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(this.canvas)}d.append($(this.canvas));if(this.dragging){this.canvas.style.zIndex="300"}}var n=function(c){return $(c).offset().left-d.offset().left};var i=function(c){return $(c).offset().top-d.offset().top};if(!this.handle1||!this.handle2){return}var h=n(this.handle1.element)+5;var g=i(this.handle1.element)+5;var p=n(this.handle2.element)+5;var m=i(this.handle2.element)+5;var f=100;var k=Math.min(h,p);var a=Math.max(h,p);var j=Math.min(g,m);var t=Math.max(g,m);var b=Math.min(Math.max(Math.abs(t-j)/2,100),300);var o=k-f;var s=j-f;var q=a-k+2*f;var l=t-j+2*f;this.canvas.style.left=o+"px";this.canvas.style.top=s+"px";this.canvas.setAttribute("width",q);this.canvas.setAttribute("height",l);h-=o;g-=s;p-=o;m-=s;var r=this.canvas.getContext("2d");r.lineCap="round";r.strokeStyle=this.outer_color;r.lineWidth=7;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke();r.strokeStyle=this.inner_color;r.lineWidth=5;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke()}});function Node(a){this.element=a;this.input_terminals={};this.output_terminals={};this.tool_errors={}}$.extend(Node.prototype,{new_input_terminal:function(a){var b=$("
")[0];this.enable_input_terminal(b,a.name,a.extensions,a.multiple);return b},enable_input_terminal:function(f,b,d,a){var g=this;var c=f.terminal=new InputTerminal(f,d,a);c.node=g;c.name=b;$(f).bind("dropinit",function(h,i){return $(i.drag).hasClass("output-terminal")&&c.can_accept(i.drag.terminal)}).bind("dropstart",function(h,i){if(i.proxy.terminal){i.proxy.terminal.connectors[0].inner_color="#BBFFBB"}}).bind("dropend",function(h,i){if(i.proxy.terminal){i.proxy.terminal.connectors[0].inner_color="#FFFFFF"}}).bind("drop",function(h,i){(new Connector(i.drag.terminal,c)).redraw()}).bind("hover",function(){if(c.connectors.length>0){var h=$("
").css({display:"none"}).appendTo("body").append($("
").append($("
").addClass("fa-icon-button fa fa-times").click(function(){$.each(c.connectors,function(j,i){if(i){i.destroy()}});h.remove()}))).bind("mouseleave",function(){$(this).remove()});h.css({top:$(f).offset().top-2,left:$(f).offset().left-h.width(),"padding-right":$(f).width()}).show()}});g.input_terminals[b]=c},enable_output_terminal:function(d,a,f){var g=this;var c=d;var b=d.terminal=new OutputTerminal(d,f);b.node=g;b.name=a;$(d).bind("dragstart",function(j,k){$(k.available).addClass("input-terminal-active");workflow.check_changes_in_active_form();var i=$('
').appendTo("#canvas-container").get(0);i.terminal=new OutputTerminal(i);var l=new Connector();l.dragging=true;l.connect(d.terminal,i.terminal);return i}).bind("drag",function(i,j){var h=function(){var l=$(j.proxy).offsetParent().offset(),k=j.offsetX-l.left,m=j.offsetY-l.top;$(j.proxy).css({left:k,top:m});j.proxy.terminal.redraw();canvas_manager.update_viewport_overlay()};h();$("#canvas-container").get(0).scroll_panel.test(i,h)}).bind("dragend",function(h,i){i.proxy.terminal.connectors[0].destroy();$(i.proxy).remove();$(i.available).removeClass("input-terminal-active");$("#canvas-container").get(0).scroll_panel.stop()});g.output_terminals[a]=b},redraw:function(){$.each(this.input_terminals,function(a,b){b.redraw()});$.each(this.output_terminals,function(a,b){b.redraw()})},destroy:function(){$.each(this.input_terminals,function(a,b){b.destroy()});$.each(this.output_terminals,function(a,b){b.destroy()});workflow.remove_node(this);$(this.element).remove()},make_active:function(){$(this.element).addClass("toolForm-active")},make_inactive:function(){var a=this.element.get(0);(function(b){b.removeChild(a);b.appendChild(a)})(a.parentNode);$(a).removeClass("toolForm-active")},init_field_data:function(h){var g=this.element;if(h.type){this.type=h.type}this.name=h.name;this.form_html=h.form_html;this.tool_state=h.tool_state;this.tool_errors=h.tool_errors;this.tooltip=h.tooltip?h.tooltip:"";this.annotation=h.annotation;this.post_job_actions=h.post_job_actions?h.post_job_actions:{};this.workflow_outputs=h.workflow_outputs?h.workflow_outputs:[];if(this.tool_errors){g.addClass("tool-node-error")}else{g.removeClass("tool-node-error")}var d=this;var c=Math.max(150,g.width());var a=g.find(".toolFormBody");a.find("div").remove();var i=$("
").appendTo(a);$.each(h.data_inputs,function(k,f){var j=d.new_input_terminal(f);var b=$("
"+f.label+"
");b.css({position:"absolute",left:-1000,top:-1000,display:"none"});$("body").append(b);c=Math.max(c,b.outerWidth());b.css({position:"",left:"",top:"",display:""});b.remove();i.append(b.prepend(j))});if((h.data_inputs.length>0)&&(h.data_outputs.length>0)){a.append($("
"))}$.each(h.data_outputs,function(k,b){var j=$("
");d.enable_output_terminal(j[0],b.name,b.extensions);var f=b.name;if(b.extensions.indexOf("input")<0){f=f+" ("+b.extensions.join(", ")+")"}var m=$("
"+f+"
");if(d.type=="tool"){var l=$("
").css({display:"none"}).append($("
").append($("").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png").click(function(){if($.inArray(b.name,d.workflow_outputs)!=-1){d.workflow_outputs.splice($.inArray(b.name,d.workflow_outputs),1);l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{d.workflow_outputs.push(b.name);l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}workflow.has_changes=true;canvas_manager.draw_overview()}))).tooltip({delay:500,title:"Mark dataset as a workflow output. All unmarked datasets will be hidden."});l.css({top:"50%",margin:"-8px 0px 0px 0px",right:8});l.show();m.append(l);if($.inArray(b.name,d.workflow_outputs)===-1){l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}m.hover(function(){l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-yellow.png")},function(){if($.inArray(b.name,d.workflow_outputs)===-1){l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}})}m.css({position:"absolute",left:-1000,top:-1000,display:"none"});$("body").append(m);c=Math.max(c,m.outerWidth()+17);m.css({position:"",left:"",top:"",display:""});m.detach();a.append(m.append(j))});g.css("width",Math.min(250,Math.max(g.width(),c)));workflow.node_changed(this)},update_field_data:function(d){var b=$(this.element),c=this;this.tool_state=d.tool_state;this.form_html=d.form_html;this.tool_errors=d.tool_errors;this.annotation=d.annotation;var f=$.parseJSON(d.post_job_actions);this.post_job_actions=f?f:{};if(this.tool_errors){b.addClass("tool-node-error")}else{b.removeClass("tool-node-error")}var g=b.find("div.inputs");var a=$("
");$.each(d.data_inputs,function(k,h){var j=c.new_input_terminal(h);g.find("div[name='"+h.name+"']").each(function(){$(this).find(".input-terminal").each(function(){var i=this.terminal.connectors[0];if(i){j.terminal.connectors[0]=i;i.handle2=j.terminal}});$(this).remove()});a.append($("
"+h.label+"
").prepend(j))});g.replaceWith(a);g.find("div.input-data-row > .terminal").each(function(){this.terminal.destroy()});this.changed();this.redraw()},error:function(d){var a=$(this.element).find(".toolFormBody");a.find("div").remove();var c="
"+d+"
";this.form_html=c;a.html(c);workflow.node_changed(this)},changed:function(){workflow.node_changed(this)}});function Workflow(a){this.canvas_container=a;this.id_counter=0;this.nodes={};this.name=null;this.has_changes=false;this.active_form_has_changes=false}$.extend(Workflow.prototype,{add_node:function(a){a.id=this.id_counter;a.element.attr("id","wf-node-step-"+a.id);this.id_counter++;this.nodes[a.id]=a;this.has_changes=true;a.workflow=this},remove_node:function(a){if(this.active_node==a){this.clear_active_node()}delete this.nodes[a.id];this.has_changes=true},remove_all:function(){wf=this;$.each(this.nodes,function(b,a){a.destroy();wf.remove_node(a)})},rectify_workflow_outputs:function(){var b=false;var a=false;$.each(this.nodes,function(c,d){if(d.workflow_outputs&&d.workflow_outputs.length>0){b=true}$.each(d.post_job_actions,function(g,f){if(f.action_type==="HideDatasetAction"){a=true}})});if(b!==false||a!==false){$.each(this.nodes,function(c,g){if(g.type==="tool"){var f=false;if(g.post_job_actions==null){g.post_job_actions={};f=true}var d=[];$.each(g.post_job_actions,function(i,h){if(h.action_type=="HideDatasetAction"){d.push(i)}});if(d.length>0){$.each(d,function(h,j){f=true;delete g.post_job_actions[j]})}if(b){$.each(g.output_terminals,function(i,j){var h=true;$.each(g.workflow_outputs,function(l,m){if(j.name===m){h=false}});if(h===true){f=true;var k={action_type:"HideDatasetAction",output_name:j.name,action_arguments:{}};g.post_job_actions["HideDatasetAction"+j.name]=null;g.post_job_actions["HideDatasetAction"+j.name]=k}})}if(workflow.active_node==g&&f===true){workflow.reload_active_node()}}})}},to_simple:function(){var a={};$.each(this.nodes,function(c,f){var g={};$.each(f.input_terminals,function(i,j){g[j.name]=null;var h=[];$.each(j.connectors,function(k,l){h[k]={id:l.handle1.node.id,output_name:l.handle1.name};g[j.name]=h})});var b={};if(f.post_job_actions){$.each(f.post_job_actions,function(j,h){var k={action_type:h.action_type,output_name:h.output_name,action_arguments:h.action_arguments};b[h.action_type+h.output_name]=null;b[h.action_type+h.output_name]=k})}if(!f.workflow_outputs){f.workflow_outputs=[]}var d={id:f.id,type:f.type,tool_id:f.tool_id,tool_state:f.tool_state,tool_errors:f.tool_errors,input_connections:g,position:$(f.element).position(),annotation:f.annotation,post_job_actions:f.post_job_actions,workflow_outputs:f.workflow_outputs};a[f.id]=d});return{steps:a}},from_simple:function(b){wf=this;var c=0;wf.name=b.name;var a=false;$.each(b.steps,function(g,f){var d=prebuild_node(f.type,f.name,f.tool_id);d.init_field_data(f);if(f.position){d.element.css({top:f.position.top,left:f.position.left})}d.id=f.id;wf.nodes[d.id]=d;c=Math.max(c,parseInt(g));if(!a&&d.type==="tool"){if(d.workflow_outputs.length>0){a=true}else{$.each(d.post_job_actions,function(i,h){if(h.action_type==="HideDatasetAction"){a=true}})}}});wf.id_counter=c+1;$.each(b.steps,function(g,f){var d=wf.nodes[g];$.each(f.input_connections,function(i,h){if(h){if(!$.isArray(h)){h=[h]}$.each(h,function(k,j){var m=wf.nodes[j.id];var n=new Connector();n.connect(m.output_terminals[j.output_name],d.input_terminals[i]);n.redraw()})}});if(a&&d.type==="tool"){$.each(d.output_terminals,function(h,i){if(d.post_job_actions["HideDatasetAction"+i.name]===undefined){d.workflow_outputs.push(i.name);callout=$(d.element).find(".callout."+i.name);callout.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png");workflow.has_changes=true}})}})},check_changes_in_active_form:function(){if(this.active_form_has_changes){this.has_changes=true;$("#right-content").find("form").submit();this.active_form_has_changes=false}},reload_active_node:function(){if(this.active_node){var a=this.active_node;this.clear_active_node();this.activate_node(a)}},clear_active_node:function(){if(this.active_node){this.active_node.make_inactive();this.active_node=null}parent.show_form_for_tool("
No node selected
")},activate_node:function(a){if(this.active_node!=a){this.check_changes_in_active_form();this.clear_active_node();parent.show_form_for_tool(a.form_html+a.tooltip,a);a.make_active();this.active_node=a}},node_changed:function(a){this.has_changes=true;if(this.active_node==a){this.check_changes_in_active_form();parent.show_form_for_tool(a.form_html+a.tooltip,a)}},layout:function(){this.check_changes_in_active_form();this.has_changes=true;var i={};var b={};$.each(this.nodes,function(l,k){if(i[l]===undefined){i[l]=0}if(b[l]===undefined){b[l]=[]}});$.each(this.nodes,function(l,k){$.each(k.input_terminals,function(m,n){$.each(n.connectors,function(p,q){var o=q.handle1.node;i[k.id]+=1;b[o.id].push(k.id)})})});node_ids_by_level=[];while(true){level_parents=[];for(var a in i){if(i[a]==0){level_parents.push(a)}}if(level_parents.length==0){break}node_ids_by_level.push(level_parents);for(var f in level_parents){var j=level_parents[f];delete i[j];for(var g in b[j]){i[b[j][g]]-=1}}}if(i.length){return}var d=this.nodes;var h=80;v_pad=30;var c=h;$.each(node_ids_by_level,function(k,l){l.sort(function(p,o){return $(d[p].element).position().top-$(d[o].element).position().top});var m=0;var n=v_pad;$.each(l,function(o,r){var q=d[r];var p=$(q.element);$(p).css({top:n,left:c});m=Math.max(m,$(p).width());n+=$(p).height()+v_pad});c+=m+h});$.each(d,function(k,l){l.redraw()})},bounds_for_all_nodes:function(){var d=Infinity,b=-Infinity,c=Infinity,a=-Infinity,f;$.each(this.nodes,function(h,g){e=$(g.element);f=e.position();d=Math.min(d,f.left);b=Math.max(b,f.left+e.width());c=Math.min(c,f.top);a=Math.max(a,f.top+e.width())});return{xmin:d,xmax:b,ymin:c,ymax:a}},fit_canvas_to_nodes:function(){var a=this.bounds_for_all_nodes();var f=this.canvas_container.position();var i=this.canvas_container.parent();var d=fix_delta(a.xmin,100);var h=fix_delta(a.ymin,100);d=Math.max(d,f.left);h=Math.max(h,f.top);var c=f.left-d;var g=f.top-h;var b=round_up(a.xmax+100,100)+d;var j=round_up(a.ymax+100,100)+h;b=Math.max(b,-c+i.width());j=Math.max(j,-g+i.height());this.canvas_container.css({left:c,top:g,width:b,height:j});this.canvas_container.children().each(function(){var k=$(this).position();$(this).css("left",k.left+d);$(this).css("top",k.top+h)})}});function fix_delta(a,b){if(a3*b){new_pos=(Math.ceil(((a%b))/b)+1)*b;return(-(a-new_pos))}return 0}function round_up(a,b){return Math.ceil(a/b)*b}function prebuild_node(l,j,r){var i=$("
");var g=new Node(i);g.type=l;if(l=="tool"){g.tool_id=r}var n=$("
"+j+"
");i.append(n);i.css("left",$(window).scrollLeft()+20);i.css("top",$(window).scrollTop()+20);var m=$("
");var h="
loading tool info...
";m.append(h);g.form_html=h;i.append(m);var k=$("
");k.append($("
").addClass("fa-icon-button fa fa-times").click(function(b){g.destroy()}));i.appendTo("#canvas-container");var d=$("#canvas-container").position();var c=$("#canvas-container").parent();var a=i.width();var q=i.height();i.css({left:(-d.left)+(c.width()/2)-(a/2),top:(-d.top)+(c.height()/2)-(q/2)});k.prependTo(n);a+=(k.width()+10);i.css("width",a);$(i).bind("dragstart",function(){workflow.activate_node(g)}).bind("dragend",function(){workflow.node_changed(this);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview()}).bind("dragclickonly",function(){workflow.activate_node(g)}).bind("drag",function(o,p){var f=$(this).offsetParent().offset(),b=p.offsetX-f.left,s=p.offsetY-f.top;$(this).css({left:b,top:s});$(this).find(".terminal").each(function(){this.terminal.redraw()})});return g}function add_node(b,d,a){var c=prebuild_node(b,d,a);workflow.add_node(c);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview();workflow.activate_node(c);return c}var ext_to_type=null;var type_to_type=null;function issubtype(b,a){b=ext_to_type[b];a=ext_to_type[a];return(type_to_type[b])&&(a in type_to_type[b])}function populate_datatype_info(a){ext_to_type=a.ext_to_class_name;type_to_type=a.class_to_classes}function ScrollPanel(a){this.panel=a}$.extend(ScrollPanel.prototype,{test:function(v,d){clearTimeout(this.timeout);var k=v.pageX,j=v.pageY,l=$(this.panel),c=l.position(),b=l.width(),i=l.height(),w=l.parent(),s=w.width(),a=w.height(),r=w.offset(),p=r.left,m=r.top,A=p+w.width(),u=m+w.height(),B=-(b-(s/2)),z=-(i-(a/2)),g=(s/2),f=(a/2),h=false,q=5,o=23;if(k-qA){if(c.left>B){var n=Math.min(o,c.left-B);l.css("left",c.left-n);h=true}}else{if(j-qu){if(c.top>z){var n=Math.min(o,c.top-B);l.css("top",(c.top-n)+"px");h=true}}}}}if(h){d();var l=this;this.timeout=setTimeout(function(){l.test(v,d)},50)}},stop:function(b,a){clearTimeout(this.timeout)}});function CanvasManager(b,a){this.cv=b;this.cc=this.cv.find("#canvas-container");this.oc=a.find("#overview-canvas");this.ov=a.find("#overview-viewport");this.init_drag()}$.extend(CanvasManager.prototype,{init_drag:function(){var b=this;var a=function(f,g){f=Math.min(f,b.cv.width()/2);f=Math.max(f,-b.cc.width()+b.cv.width()/2);g=Math.min(g,b.cv.height()/2);g=Math.max(g,-b.cc.height()+b.cv.height()/2);b.cc.css({left:f,top:g});b.update_viewport_overlay()};this.cc.each(function(){this.scroll_panel=new ScrollPanel(this)});var d,c;this.cv.bind("dragstart",function(){var g=$(this).offset();var f=b.cc.position();c=f.top-g.top;d=f.left-g.left}).bind("drag",function(f,g){a(g.offsetX+d,g.offsetY+c)}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});this.ov.bind("drag",function(k,l){var h=b.cc.width(),n=b.cc.height(),m=b.oc.width(),j=b.oc.height(),f=$(this).offsetParent().offset(),i=l.offsetX-f.left,g=l.offsetY-f.top;a(-(i/m*h),-(g/j*n))}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});$("#overview-border").bind("drag",function(g,i){var j=$(this).offsetParent();var h=j.offset();var f=Math.max(j.width()-(i.offsetX-h.left),j.height()-(i.offsetY-h.top));$(this).css({width:f,height:f});b.draw_overview()});$("#overview-border div").bind("drag",function(){})},update_viewport_overlay:function(){var b=this.cc,f=this.cv,a=this.oc,c=this.ov,d=b.width(),j=b.height(),i=a.width(),g=a.height(),h=b.position();c.css({left:-(h.left/d*i),top:-(h.top/j*g),width:(f.width()/d*i)-2,height:(f.height()/j*g)-2})},draw_overview:function(){var j=$("#overview-canvas"),m=j.parent().parent().width(),i=j.get(0).getContext("2d"),d=$("#canvas-container").width(),l=$("#canvas-container").height();var g,a,k,f;var h=this.cv.width();var b=this.cv.height();if(d0){i.fillStyle="#E8A92D";i.strokeStyle="#E8A92D"}}i.fillRect(c,r,o,p);i.strokeRect(c,r,o,p)});this.update_viewport_overlay()}}); \ No newline at end of file diff --git a/static/scripts/packed/galaxy.workflows.js b/static/scripts/packed/galaxy.workflows.js index 32ca6a53869..3c353ebb802 100644 --- a/static/scripts/packed/galaxy.workflows.js +++ b/static/scripts/packed/galaxy.workflows.js @@ -1 +1 @@ -$(function(){if(window.lt_ie_7){show_modal("Browser not supported","Sorry, the workflow editor is not supported for IE6 and below.");return}$("#tool-search-query").click(function(){$(this).focus();$(this).select()}).keyup(function(){$(this).css("font-style","normal");if(this.value.length<3){reset_tool_search(false)}else{if(this.value!=this.lastValue){$(this).addClass("search_active");var g=this.value+"*";if(this.timer){clearTimeout(this.timer)}$("#search-spinner").show();this.timer=setTimeout(function(){$.get(tool_search_url,{query:g},function(i){$("#search-no-results").hide();$(".toolSectionWrapper").hide();$(".toolSectionWrapper").find(".toolTitle").hide();if(i.length!=0){var h=$.map(i,function(k,j){return"link-"+k});$(h).each(function(j,k){$("[id='"+k+"']").parent().addClass("search_match");$("[id='"+k+"']").parent().show().parent().parent().show().parent().show()});$(".toolPanelLabel").each(function(){var l=$(this);var k=l.next();var j=true;while(k.length!==0&&k.hasClass("toolTitle")){if(k.is(":visible")){j=false;break}else{k=k.next()}}if(j){l.hide()}})}else{$("#search-no-results").show()}$("#search-spinner").hide()},"json")},200)}}this.lastValue=this.value});canvas_manager=new CanvasManager($("#canvas-viewport"),$("#overview"));reset();$.ajax({url:get_datatypes_url,dataType:"json",cache:false,success:function(g){populate_datatype_info(g);$.ajax({url:load_workflow_url,data:{id:workflow_id,_:"true"},dataType:"json",cache:false,success:function(h){reset();workflow.from_simple(h);workflow.has_changes=false;workflow.fit_canvas_to_nodes();scroll_to_nodes();canvas_manager.draw_overview();upgrade_message="";$.each(h.upgrade_messages,function(j,i){upgrade_message+=("
  • Step "+(parseInt(j,10)+1)+": "+workflow.nodes[j].name+"
      ");$.each(i,function(k,l){upgrade_message+="
    • "+l+"
    • "});upgrade_message+="
  • "});if(upgrade_message){show_modal("Workflow loaded with changes","Problems were encountered loading this workflow (possibly a result of tool upgrades). Please review the following parameters and then save.
      "+upgrade_message+"
    ",{Continue:hide_modal})}else{hide_modal()}show_workflow_parameters()},beforeSubmit:function(h){show_message("Loading workflow","progress")}})}});$(document).ajaxStart(function(){active_ajax_call=true;$(document).bind("ajaxStop.global",function(){active_ajax_call=false})});$(document).ajaxError(function(i,g){var h=g.responseText||g.statusText||"Could not connect to server";show_modal("Server error",h,{"Ignore error":hide_modal});return false});make_popupmenu($("#workflow-options-button"),{Save:save_current_workflow,Run:function(){window.location=run_workflow_url},"Edit Attributes":c,"Auto Re-layout":f,Close:close_editor});function b(){workflow.clear_active_node();$(".right-content").hide();var j="";for(var h in workflow.nodes){var i=workflow.nodes[h];if(i.type=="tool"){j+="
    Step "+i.id+" - "+i.name+"
    ";for(var k in i.output_terminals){var g=i.output_terminals[k];if($.inArray(g.name,i.workflow_outputs)!=-1){j+="

    "+g.name+"

    "}else{j+="

    "+g.name+"

    "}}j+="
    "}}$("#output-fill-area").html(j);$("#output-fill-area input").bind("click",function(){var n=this.name.split("|")[0];var l=this.name.split("|")[1];if(this.checked){if($.inArray(l,workflow.nodes[n].workflow_outputs)==-1){workflow.nodes[n].workflow_outputs.push(l)}}else{while($.inArray(l,workflow.nodes[n].workflow_outputs)!=-1){var m=$.inArray(l,workflow.nodes[n].workflow_outputs);workflow.nodes[n].workflow_outputs=workflow.nodes[n].workflow_outputs.slice(0,m).concat(workflow.nodes[n].workflow_outputs.slice(m+1))}}workflow.has_changes=true});$("#workflow-output-area").show()}function f(){workflow.layout();workflow.fit_canvas_to_nodes();scroll_to_nodes();canvas_manager.draw_overview()}function c(){workflow.clear_active_node();$(".right-content").hide();$("#edit-attributes").show()}overview_size=$.jStorage.get("overview-size");if(overview_size!==undefined){$("#overview-border").css({width:overview_size,height:overview_size})}if($.jStorage.get("overview-off")){d()}else{e()}$("#overview-border").bind("dragend",function(h,j){var k=$(this).offsetParent();var i=k.offset();var g=Math.max(k.width()-(j.offsetX-i.left),k.height()-(j.offsetY-i.top));$.jStorage.set("overview-size",g+"px")});function e(){$.jStorage.set("overview-off",false);$("#overview-border").css("right","0px");$("#close-viewport").css("background-position","0px 0px")}function d(){$.jStorage.set("overview-off",true);$("#overview-border").css("right","20000px");$("#close-viewport").css("background-position","12px 0px")}$("#close-viewport").click(function(){if($("#overview-border").css("right")==="0px"){d()}else{e()}});window.onbeforeunload=function(){if(workflow&&workflow.has_changes){return"There are unsaved changes to your workflow which will be lost."}};$("div.toolSectionBody").hide();$("div.toolSectionTitle > span").wrap("");var a=null;$("div.toolSectionTitle").each(function(){var g=$(this).next("div.toolSectionBody");$(this).click(function(){if(g.is(":hidden")){if(a){a.slideUp("fast")}a=g;g.slideDown("fast")}else{g.slideUp("fast");a=null}})});async_save_text("workflow-name","workflow-name",rename_async_url,"new_name");$("#workflow-tag").click(function(){$(".tag-area").click();return false});async_save_text("workflow-annotation","workflow-annotation",annotate_async_url,"new_annotation",25,true,4)});function reset(){if(workflow){workflow.remove_all()}workflow=new Workflow($("#canvas-container"))}function scroll_to_nodes(){var a=$("#canvas-viewport");var d=$("#canvas-container");var c,b;if(d.width().toolForm:last>.toolFormTitle>.buttons").click(function(){action_to_rem=$(this).closest(".toolForm",".action_tag").children(".action_tag:first").text();$(this).closest(".toolForm").remove();delete workflow.active_node.post_job_actions[action_to_rem];workflow.active_form_has_changes=true})}function display_pja_list(){return pja_list}function display_file_list(b){addlist="";return addlist}function new_pja(d,b,a){if(a.post_job_actions===undefined){a.post_job_actions={}}if(a.post_job_actions[d+b]===undefined){var c={};c.action_type=d;c.output_name=b;a.post_job_actions[d+b]=null;a.post_job_actions[d+b]=c;display_pja(c,a);workflow.active_form_has_changes=true;return true}else{return false}}function show_workflow_parameters(){var c=/\$\{.+?\}/g;var b=[];var f=$("#workflow-parameters-container");var e=$("#workflow-parameters-box");var a="";var d=[];$.each(workflow.nodes,function(g,h){var i=h.form_html.match(c);if(i){d=d.concat(i)}if(h.post_job_actions){$.each(h.post_job_actions,function(j,l){if(l.action_arguments){$.each(l.action_arguments,function(m,n){var o=n.match(c);if(o){d=d.concat(o)}})}});if(d){$.each(d,function(j,l){if($.inArray(l,b)===-1){b.push(l)}})}}});if(b&&b.length!==0){$.each(b,function(g,h){a+="
    "+h.substring(2,h.length-1)+"
    "});f.html(a);e.show()}else{f.html(a);e.hide()}}function show_form_for_tool(c,b){$(".right-content").hide();$("#right-content").show().html(c);if(b){$("#right-content").find(".toolForm:first").after("

    Edit Step Attributes
    Add an annotation or notes to this step; annotations are available when a workflow is viewed.
    ")}if(b&&b.type=="tool"){pjastr="

    Edit Step Actions
    "+display_pja_list()+"
    "+display_file_list(b)+"
    Create
    ";pjastr+="
    Add actions to this step; actions are applied when this workflow step completes.
    ";$("#right-content").find(".toolForm").after(pjastr);for(var a in b.post_job_actions){if(a!="undefined"){display_pja(b.post_job_actions[a],b)}}$("#add_pja").click(function(){new_pja($("#new_pja_list").val(),$("#node_data_list").val(),b)})}$("#right-content").find("form").ajaxForm({type:"POST",dataType:"json",success:function(d){workflow.active_form_has_changes=false;b.update_field_data(d);show_workflow_parameters()},beforeSubmit:function(d){d.push({name:"tool_state",value:b.tool_state});d.push({name:"_",value:"true"})}}).each(function(){var d=this;$(this).find("select[refresh_on_change='true']").change(function(){$(d).submit()});$(this).find(".popupmenu").each(function(){var g=$(this).parents("div.form-row").attr("id");var e=$('▼');var f={};$(this).find("button").each(function(){var h=$(this).attr("name");var i=$(this).attr("value");f[$(this).text()]=function(){$(d).append("").submit()}});e.insertAfter(this);$(this).remove();make_popupmenu(e,f)});$(this).find("input,textarea,select").each(function(){$(this).bind("focus click",function(){workflow.active_form_has_changes=true})})})}var close_editor=function(){workflow.check_changes_in_active_form();if(workflow&&workflow.has_changes){do_close=function(){window.onbeforeunload=undefined;window.document.location=workflow_index_url};show_modal("Close workflow editor","There are unsaved changes to your workflow which will be lost.",{Cancel:hide_modal,"Save Changes":function(){save_current_workflow(null,do_close)}},{"Don't Save":do_close})}else{window.document.location=workflow_index_url}};var save_current_workflow=function(b,c){show_message("Saving workflow","progress");workflow.check_changes_in_active_form();if(!workflow.has_changes){hide_modal();if(c){c()}return}workflow.rectify_workflow_outputs();var a=function(d){$.ajax({url:save_workflow_url,type:"POST",data:{id:workflow_id,workflow_data:function(){return JSON.stringify(workflow.to_simple())},_:"true"},dataType:"json",success:function(g){var e=$("
    ").text(g.message);if(g.errors){e.addClass("warningmark");var f=$("
      ");$.each(g.errors,function(j,h){$("
    • ").text(h).appendTo(f)});e.append(f)}else{e.addClass("donemark")}workflow.name=g.name;workflow.has_changes=false;workflow.stored=true;show_workflow_parameters();if(g.errors){show_modal("Saving workflow",e,{Ok:hide_modal})}else{if(d){d()}hide_modal()}}})};if(active_ajax_call){$(document).bind("ajaxStop.save_workflow",function(){$(document).unbind("ajaxStop.save_workflow");a();$(document).unbind("ajaxStop.save_workflow");active_ajax_call=false})}else{a(c)}}; \ No newline at end of file +$(function(){if(window.lt_ie_7){show_modal("Browser not supported","Sorry, the workflow editor is not supported for IE6 and below.");return}$("#tool-search-query").click(function(){$(this).focus();$(this).select()}).keyup(function(){$(this).css("font-style","normal");if(this.value.length<3){reset_tool_search(false)}else{if(this.value!=this.lastValue){$(this).addClass("search_active");var g=this.value+"*";if(this.timer){clearTimeout(this.timer)}$("#search-spinner").show();this.timer=setTimeout(function(){$.get(tool_search_url,{query:g},function(i){$("#search-no-results").hide();$(".toolSectionWrapper").hide();$(".toolSectionWrapper").find(".toolTitle").hide();if(i.length!=0){var h=$.map(i,function(k,j){return"link-"+k});$(h).each(function(j,k){$("[id='"+k+"']").parent().addClass("search_match");$("[id='"+k+"']").parent().show().parent().parent().show().parent().show()});$(".toolPanelLabel").each(function(){var l=$(this);var k=l.next();var j=true;while(k.length!==0&&k.hasClass("toolTitle")){if(k.is(":visible")){j=false;break}else{k=k.next()}}if(j){l.hide()}})}else{$("#search-no-results").show()}$("#search-spinner").hide()},"json")},200)}}this.lastValue=this.value});canvas_manager=new CanvasManager($("#canvas-viewport"),$("#overview"));reset();$.ajax({url:get_datatypes_url,dataType:"json",cache:false,success:function(g){populate_datatype_info(g);$.ajax({url:load_workflow_url,data:{id:workflow_id,_:"true"},dataType:"json",cache:false,success:function(h){reset();workflow.from_simple(h);workflow.has_changes=false;workflow.fit_canvas_to_nodes();scroll_to_nodes();canvas_manager.draw_overview();upgrade_message="";$.each(h.upgrade_messages,function(j,i){upgrade_message+=("
    • Step "+(parseInt(j,10)+1)+": "+workflow.nodes[j].name+"
        ");$.each(i,function(k,l){upgrade_message+="
      • "+l+"
      • "});upgrade_message+="
    • "});if(upgrade_message){show_modal("Workflow loaded with changes","Problems were encountered loading this workflow (possibly a result of tool upgrades). Please review the following parameters and then save.
        "+upgrade_message+"
      ",{Continue:hide_modal})}else{hide_modal()}show_workflow_parameters()},beforeSubmit:function(h){show_message("Loading workflow","progress")}})}});$(document).ajaxStart(function(){active_ajax_call=true;$(document).bind("ajaxStop.global",function(){active_ajax_call=false})});$(document).ajaxError(function(i,g){var h=g.responseText||g.statusText||"Could not connect to server";show_modal("Server error",h,{"Ignore error":hide_modal});return false});make_popupmenu($("#workflow-options-button"),{Save:save_current_workflow,Run:function(){window.location=run_workflow_url},"Edit Attributes":c,"Auto Re-layout":f,Close:close_editor});function b(){workflow.clear_active_node();$(".right-content").hide();var j="";for(var h in workflow.nodes){var i=workflow.nodes[h];if(i.type=="tool"){j+="
      Step "+i.id+" - "+i.name+"
      ";for(var k in i.output_terminals){var g=i.output_terminals[k];if($.inArray(g.name,i.workflow_outputs)!=-1){j+="

      "+g.name+"

      "}else{j+="

      "+g.name+"

      "}}j+="
      "}}$("#output-fill-area").html(j);$("#output-fill-area input").bind("click",function(){var n=this.name.split("|")[0];var l=this.name.split("|")[1];if(this.checked){if($.inArray(l,workflow.nodes[n].workflow_outputs)==-1){workflow.nodes[n].workflow_outputs.push(l)}}else{while($.inArray(l,workflow.nodes[n].workflow_outputs)!=-1){var m=$.inArray(l,workflow.nodes[n].workflow_outputs);workflow.nodes[n].workflow_outputs=workflow.nodes[n].workflow_outputs.slice(0,m).concat(workflow.nodes[n].workflow_outputs.slice(m+1))}}workflow.has_changes=true});$("#workflow-output-area").show()}function f(){workflow.layout();workflow.fit_canvas_to_nodes();scroll_to_nodes();canvas_manager.draw_overview()}function c(){workflow.clear_active_node();$(".right-content").hide();$("#edit-attributes").show()}overview_size=$.jStorage.get("overview-size");if(overview_size!==undefined){$("#overview-border").css({width:overview_size,height:overview_size})}if($.jStorage.get("overview-off")){d()}else{e()}$("#overview-border").bind("dragend",function(h,j){var k=$(this).offsetParent();var i=k.offset();var g=Math.max(k.width()-(j.offsetX-i.left),k.height()-(j.offsetY-i.top));$.jStorage.set("overview-size",g+"px")});function e(){$.jStorage.set("overview-off",false);$("#overview-border").css("right","0px");$("#close-viewport").css("background-position","0px 0px")}function d(){$.jStorage.set("overview-off",true);$("#overview-border").css("right","20000px");$("#close-viewport").css("background-position","12px 0px")}$("#close-viewport").click(function(){if($("#overview-border").css("right")==="0px"){d()}else{e()}});window.onbeforeunload=function(){if(workflow&&workflow.has_changes){return"There are unsaved changes to your workflow which will be lost."}};$("div.toolSectionBody").hide();$("div.toolSectionTitle > span").wrap("");var a=null;$("div.toolSectionTitle").each(function(){var g=$(this).next("div.toolSectionBody");$(this).click(function(){if(g.is(":hidden")){if(a){a.slideUp("fast")}a=g;g.slideDown("fast")}else{g.slideUp("fast");a=null}})});async_save_text("workflow-name","workflow-name",rename_async_url,"new_name");$("#workflow-tag").click(function(){$(".tag-area").click();return false});async_save_text("workflow-annotation","workflow-annotation",annotate_async_url,"new_annotation",25,true,4)});function reset(){if(workflow){workflow.remove_all()}workflow=new Workflow($("#canvas-container"))}function scroll_to_nodes(){var a=$("#canvas-viewport");var d=$("#canvas-container");var c,b;if(d.width().toolForm:last>.toolFormTitle>.buttons").click(function(){action_to_rem=$(this).closest(".toolForm",".action_tag").children(".action_tag:first").text();$(this).closest(".toolForm").remove();delete workflow.active_node.post_job_actions[action_to_rem];workflow.active_form_has_changes=true})}function display_pja_list(){return pja_list}function display_file_list(b){addlist="";return addlist}function new_pja(d,b,a){if(a.post_job_actions===undefined){a.post_job_actions={}}if(a.post_job_actions[d+b]===undefined){var c={};c.action_type=d;c.output_name=b;a.post_job_actions[d+b]=null;a.post_job_actions[d+b]=c;display_pja(c,a);workflow.active_form_has_changes=true;return true}else{return false}}function show_workflow_parameters(){var c=/\$\{.+?\}/g;var b=[];var f=$("#workflow-parameters-container");var e=$("#workflow-parameters-box");var a="";var d=[];$.each(workflow.nodes,function(g,h){var i=h.form_html.match(c);if(i){d=d.concat(i)}if(h.post_job_actions){$.each(h.post_job_actions,function(j,l){if(l.action_arguments){$.each(l.action_arguments,function(m,n){var o=n.match(c);if(o){d=d.concat(o)}})}});if(d){$.each(d,function(j,l){if($.inArray(l,b)===-1){b.push(l)}})}}});if(b&&b.length!==0){$.each(b,function(g,h){a+="
      "+h.substring(2,h.length-1)+"
      "});f.html(a);e.show()}else{f.html(a);e.hide()}}function show_form_for_tool(c,b){$(".right-content").hide();$("#right-content").show().html(c);if(b){$("#right-content").find(".toolForm:first").after("

      Edit Step Attributes
      Add an annotation or notes to this step; annotations are available when a workflow is viewed.
      ")}if(b&&b.type=="tool"){pjastr="

      Edit Step Actions
      "+display_pja_list()+"
      "+display_file_list(b)+"
      Create
      ";pjastr+="
      Add actions to this step; actions are applied when this workflow step completes.
      ";$("#right-content").find(".toolForm").after(pjastr);for(var a in b.post_job_actions){if(a!="undefined"){display_pja(b.post_job_actions[a],b)}}$("#add_pja").click(function(){new_pja($("#new_pja_list").val(),$("#node_data_list").val(),b)})}$("#right-content").find("form").ajaxForm({type:"POST",dataType:"json",success:function(d){workflow.active_form_has_changes=false;b.update_field_data(d);show_workflow_parameters()},beforeSubmit:function(d){d.push({name:"tool_state",value:b.tool_state});d.push({name:"_",value:"true"})}}).each(function(){var d=this;$(this).find("select[refresh_on_change='true']").change(function(){$(d).submit()});$(this).find(".popupmenu").each(function(){var g=$(this).parents("div.form-row").attr("id");var e=$('▼');var f={};$(this).find("button").each(function(){var h=$(this).attr("name");var i=$(this).attr("value");f[$(this).text()]=function(){$(d).append("").submit()}});e.insertAfter(this);$(this).remove();make_popupmenu(e,f)});$(this).find("input,textarea,select").each(function(){$(this).bind("focus click",function(){workflow.active_form_has_changes=true})})})}var close_editor=function(){workflow.check_changes_in_active_form();if(workflow&&workflow.has_changes){do_close=function(){window.onbeforeunload=undefined;window.document.location=workflow_index_url};show_modal("Close workflow editor","There are unsaved changes to your workflow which will be lost.",{Cancel:hide_modal,"Save Changes":function(){save_current_workflow(null,do_close)}},{"Don't Save":do_close})}else{window.document.location=workflow_index_url}};var save_current_workflow=function(b,c){show_message("Saving workflow","progress");workflow.check_changes_in_active_form();if(!workflow.has_changes){hide_modal();if(c){c()}return}workflow.rectify_workflow_outputs();var a=function(d){$.ajax({url:save_workflow_url,type:"POST",data:{id:workflow_id,workflow_data:function(){return JSON.stringify(workflow.to_simple())},_:"true"},dataType:"json",success:function(g){var e=$("
      ").text(g.message);if(g.errors){e.addClass("warningmark");var f=$("
        ");$.each(g.errors,function(j,h){$("
      • ").text(h).appendTo(f)});e.append(f)}else{e.addClass("donemark")}workflow.name=g.name;workflow.has_changes=false;workflow.stored=true;show_workflow_parameters();if(g.errors){show_modal("Saving workflow",e,{Ok:hide_modal})}else{if(d){d()}hide_modal()}}})};if(active_ajax_call){$(document).bind("ajaxStop.save_workflow",function(){$(document).unbind("ajaxStop.save_workflow");a();$(document).unbind("ajaxStop.save_workflow");active_ajax_call=false})}else{a(c)}}; \ No newline at end of file diff --git a/static/scripts/packed/mvc/library/library-folderlist-view.js b/static/scripts/packed/mvc/library/library-folderlist-view.js index 0ab07cf8b01..d940ceb3eeb 100644 --- a/static/scripts/packed/mvc/library/library-folderlist-view.js +++ b/static/scripts/packed/mvc/library/library-folderlist-view.js @@ -1 +1 @@ -define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(a,c,d,b){var e=Backbone.View.extend({el:"#center",progress:0,progressStep:1,lastSelectedHistory:"",modal:null,folders:null,initialize:function(){this.folders=[];this.queue=jQuery.Deferred();this.queue.resolve()},templateFolder:function(){var f=[];f.push('
        ');f.push('

        Data Libraries Beta Test. This is work in progress. Please report problems & ideas via email and Trello.

        ');f.push('
        ');f.push(' ');f.push(' ');f.push(' ");f.push("
        ");f.push('");f.push('
    ');f.push(" ");f.push(' ');f.push(' ');f.push(" ");f.push(" ");f.push(" ");f.push(" ");f.push(" ");f.push(" ");f.push(' ');f.push(" ");f.push(" ");f.push(" ");f.push(" ");f.push(" ");f.push(" ");f.push(" <% _.each(items, function(content_item) { %>");f.push(' <% if (content_item.get("type") === "folder") { %>');f.push(' ');f.push(" ");f.push(" ");f.push(" ");f.push(" ");f.push(' ');f.push(' ');f.push(" ");f.push(" <% } else { %>");f.push(' ');f.push(" ");f.push(' ');f.push(' ');f.push(' ');f.push(' ');f.push(' ');f.push(" ");f.push(" <% } %> ");f.push(" <% }); %>");f.push(" ");f.push(" ");f.push("
    namedata typesizedate (UTC)
    " title="Go to parent folder" class="btn_open_folder btn btn-default btn-xs">..
    ");f.push(' ');f.push(" ");f.push(' <%- content_item.get("name") %>');f.push(' <% if (content_item.get("item_count") === 0) { %>');f.push(' (empty folder)');f.push(" <% } %>");f.push(" folder<%= _.escape(content_item.get("item_count")) %> item(s)<%= _.escape(content_item.get("time_updated")) %>
    ");f.push(' ');f.push(" <%- content_item.get("name") %><%= _.escape(content_item.get("data_type")) %><%= _.escape(content_item.get("readable_size")) %><%= _.escape(content_item.get("time_updated")) %>
    ");f.push("
    ");return f.join("")},templateDatasetModal:function(){var f=[];f.push('");return f.join("")},templateHistorySelectInModal:function(){var f=[];f.push('');f.push("Select history: ");f.push('");f.push("");return f.join("")},templateBulkImportInModal:function(){var f=[];f.push('');f.push("Select history: ");f.push('");f.push("");return f.join("")},templateProgressBar:function(){var f=[];f.push('
    ');f.push("Importing selected datasets to history <%= _.escape(history_name) %>");f.push("
    ");f.push('
    ');f.push('
    ');f.push(' 0% Complete');f.push("
    ");f.push("
    ");f.push("");return f.join("")},templateNewFolderInModal:function(){tmpl_array=[];tmpl_array.push('
    ');tmpl_array.push("
    ");tmpl_array.push('');tmpl_array.push('');tmpl_array.push("
    ");tmpl_array.push("
    ");return tmpl_array.join("")},events:{"click #select-all-checkboxes":"selectAll","click #toolbtn_bulk_import":"modalBulkImport","click #toolbtn_dl":"bulkDownload","click #toolbtn_create_folder":"createFolderFromModal","click .library-dataset":"showDatasetDetails","click .dataset_row":"selectClickedRow"},render:function(f){$("#center").css("overflow","auto");view=this;var h=this;var g=new b.FolderContainer({id:f.id});g.url=g.attributes.urlRoot+f.id+"/contents";g.fetch({success:function(j){for(var l=0;l=100000000000){f=f/100000000000;g="TB"}else{if(f>=100000000){f=f/100000000;g="GB"}else{if(f>=100000){f=f/100000;g="MB"}else{if(f>=100){f=f/100;g="KB"}else{f=f*10;g="b"}}}}return(Math.round(f)/10)+g},showDatasetDetails:function(i){i.preventDefault();var j=$(i.target).parent().parent().parent().attr("id");if(typeof j==="undefined"){j=$(i.target).parent().attr("id")}if(typeof j==="undefined"){j=$(i.target).parent().parent().attr("id")}var h=new b.Item();var g=new b.GalaxyHistories();h.id=j;var f=this;h.fetch({success:function(k){g.fetch({success:function(l){f.renderModalAfterFetch(k,l)},error:function(){d.error("An error occured during fetching histories:(");f.renderModalAfterFetch(k)}})},error:function(){d.error("An error occured during loading dataset details :(")}})},renderModalAfterFetch:function(k,h){var i=this.size_to_string(k.get("file_size"));var j=_.template(this.templateDatasetModal(),{item:k,size:i});var g=this;this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Dataset Details",body:j,buttons:{Import:function(){g.importCurrentIntoHistory()},Download:function(){g.downloadCurrent()},Close:function(){g.modal.hide()}}});$(".peek").html("Peek:"+k.get("peek"));if(typeof history.models!==undefined){var f=_.template(this.templateHistorySelectInModal(),{histories:h.models});$(this.modal.elMain).find(".buttons").prepend(f);if(g.lastSelectedHistory.length>0){$(this.modal.elMain).find("#dataset_import_single").val(g.lastSelectedHistory)}}},downloadCurrent:function(){this.modal.disableButton("Import");this.modal.disableButton("Download");var f=[];f.push($("#id_row").attr("data-id"));var g="/api/libraries/datasets/download/uncompressed";var h={ldda_ids:f};folderContentView.processDownload(g,h);this.modal.enableButton("Import");this.modal.enableButton("Download")},importCurrentIntoHistory:function(){this.modal.disableButton("Import");this.modal.disableButton("Download");var h=$(this.modal.elMain).find("select[name=dataset_import_single] option:selected").val();this.lastSelectedHistory=h;var f=$("#id_row").attr("data-id");var i=new b.HistoryItem();var g=this;i.url=i.urlRoot+h+"/contents";i.save({content:f,source:"library"},{success:function(){d.success("Dataset imported");g.modal.enableButton("Import");g.modal.enableButton("Download")},error:function(){d.error("An error occured! Dataset not imported. Please try again.");g.modal.enableButton("Import");g.modal.enableButton("Download")}})},selectAll:function(g){var f=g.target.checked;that=this;$(":checkbox").each(function(){this.checked=f;$row=$(this.parentElement.parentElement);(f)?that.makeDarkRow($row):that.makeWhiteRow($row)});this.checkTools()},selectClickedRow:function(g){var i="";var f;var h;if(g.target.localName==="input"){i=g.target;f=$(g.target.parentElement.parentElement);h="input"}else{if(g.target.localName==="td"){i=$("#"+g.target.parentElement.id).find(":checkbox")[0];f=$(g.target.parentElement);h="td"}}if(i.checked){if(h==="td"){i.checked="";this.makeWhiteRow(f)}else{if(h==="input"){this.makeDarkRow(f)}}}else{if(h==="td"){i.checked="selected";this.makeDarkRow(f)}else{if(h==="input"){this.makeWhiteRow(f)}}}this.checkTools()},makeDarkRow:function(f){f.removeClass("light");f.find("a").removeClass("light");f.addClass("dark");f.find("a").addClass("dark");f.find("span").removeClass("fa-file-o");f.find("span").addClass("fa-file")},makeWhiteRow:function(f){f.removeClass("dark");f.find("a").removeClass("dark");f.addClass("light");f.find("a").addClass("light");f.find("span").addClass("fa-file-o");f.find("span").removeClass("fa-file")},checkTools:function(){var f=$("#folder_table").find(":checked");if(f.length>0){$("#toolbtn_bulk_import").show();$("#toolbtn_dl").show()}else{$("#toolbtn_bulk_import").hide();$("#toolbtn_dl").hide()}},modalBulkImport:function(){var g=this;var f=new b.GalaxyHistories();f.fetch({success:function(h){var i=_.template(g.templateBulkImportInModal(),{histories:h.models});g.modal=Galaxy.modal;g.modal.show({closing_events:true,title:"Import into History",body:i,buttons:{Import:function(){g.importAllIntoHistory()},Close:function(){g.modal.hide()}}})},error:function(){d.error("An error occured :(")}})},importAllIntoHistory:function(){this.modal.disableButton("Import");var h=$("select[name=dataset_import_bulk] option:selected").val();var m=$("select[name=dataset_import_bulk] option:selected").text();var o=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!=""){o.push(this.parentElement.parentElement.id)}});var n=_.template(this.templateProgressBar(),{history_name:m});$(this.modal.elMain).find(".modal-body").html(n);var j=100/o.length;this.initProgress(j);var f=[];for(var g=o.length-1;g>=0;g--){library_dataset_id=o[g];var k=new b.HistoryItem();var l=this;k.url=k.urlRoot+h+"/contents";k.content=library_dataset_id;k.source="library";f.push(k)}this.chainCall(f)},chainCall:function(g){var f=this;var h=g.pop();if(typeof h==="undefined"){d.success("All datasets imported");this.modal.hide();return}var i=$.when(h.save({content:h.content,source:h.source})).done(function(j){f.updateProgress();f.chainCall(g)})},initProgress:function(f){this.progress=0;this.progressStep=f},updateProgress:function(){this.progress+=this.progressStep;$(".progress-bar-import").width(Math.round(this.progress)+"%");txt_representation=Math.round(this.progress)+"% Complete";$(".completion_span").text(txt_representation)},download:function(f,j){var h=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!=""){h.push(this.parentElement.parentElement.id)}});var g="/api/libraries/datasets/download/"+j;var i={ldda_ids:h};this.processDownload(g,i,"get")},processDownload:function(g,h,i){if(g&&h){h=typeof h=="string"?h:$.param(h);var f="";$.each(h.split("&"),function(){var j=this.split("=");f+=''});$('
    '+f+"
    ").appendTo("body").submit().remove();d.info("Your download will begin soon")}},createFolderFromModal:function(){event.preventDefault();event.stopPropagation();var f=this;this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Folder",body:this.templateNewFolderInModal(),buttons:{Create:function(){f.create_new_folder_event()},Close:function(){f.modal.hide();f.modal=null}}})},create_new_folder_event:function(){var f=this.serialize_new_folder();if(this.validate_new_folder(f)){var h=new b.FolderAsModel();url_items=Backbone.history.fragment.split("/");current_folder_id=url_items[url_items.length-1];h.url=h.urlRoot+"/"+current_folder_id;var g=this;h.save(f,{success:function(i){g.modal.hide();d.success("Folder created");g.render({id:current_folder_id})},error:function(){d.error("An error occured :(")}})}else{d.error("Folder's name is missing")}return false},serialize_new_folder:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val()}},validate_new_folder:function(f){return f.name!==""}});return{FolderContentView:e}}); \ No newline at end of file +define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model","mvc/library/library-folderrow-view"],function(c,e,f,d,a){var b=Backbone.View.extend({el:"#folder_items_element",progress:0,progressStep:1,modal:null,folderContainer:null,events:{"click #select-all-checkboxes":"selectAll","click .dataset_row":"selectClickedRow"},initialize:function(g){var h=this;this.options=_.defaults(this.options||{},g);this.queue=jQuery.Deferred();this.queue.resolve();this.folderContainer=new d.FolderContainer({id:this.options.id});this.folderContainer.url=this.folderContainer.attributes.urlRoot+this.options.id+"/contents";this.folderContainer.fetch({success:function(i){h.render()},error:function(){f.error("An error occured :(")}})},render:function(h){this.options=_.defaults(this.options||{},h);var k=this.templateFolder();var l=false;for(var j=0;j0){this.renderRows()}if(this.folderContainer.attributes.metadata.can_add_library_item===true){Galaxy.libraries.folderToolbarView.configureElements({can_add_library_item:this.folderContainer.attributes.metadata.can_add_library_item,contains_file:l})}$("#center [data-toggle]").tooltip();$("#center").css("overflow","auto")},renderRows:function(){for(var j=0;j=100000000000){g=g/100000000000;h="TB"}else{if(g>=100000000){g=g/100000000;h="GB"}else{if(g>=100000){g=g/100000;h="MB"}else{if(g>=100){g=g/100;h="KB"}else{g=g*10;h="b"}}}}return(Math.round(g)/10)+h},selectAll:function(h){var g=h.target.checked;that=this;$(":checkbox").each(function(){this.checked=g;$row=$(this.parentElement.parentElement);(g)?that.makeDarkRow($row):that.makeWhiteRow($row)})},selectClickedRow:function(h){var j="";var g;var i;if(h.target.localName==="input"){j=h.target;g=$(h.target.parentElement.parentElement);i="input"}else{if(h.target.localName==="td"){j=$("#"+h.target.parentElement.id).find(":checkbox")[0];g=$(h.target.parentElement);i="td"}}if(j.checked){if(i==="td"){j.checked="";this.makeWhiteRow(g)}else{if(i==="input"){this.makeDarkRow(g)}}}else{if(i==="td"){j.checked="selected";this.makeDarkRow(g)}else{if(i==="input"){this.makeWhiteRow(g)}}}},makeDarkRow:function(g){g.removeClass("light");g.find("a").removeClass("light");g.addClass("dark");g.find("a").addClass("dark");g.find("span").removeClass("fa-file-o");g.find("span").addClass("fa-file")},makeWhiteRow:function(g){g.removeClass("dark");g.find("a").removeClass("dark");g.addClass("light");g.find("a").addClass("light");g.find("span").addClass("fa-file-o");g.find("span").removeClass("fa-file")},templateFolder:function(){var g=[];g.push('");g.push('');g.push(" ");g.push(' ');g.push(' ');g.push(" ");g.push(" ");g.push(" ");g.push(" ");g.push(" ");g.push(' ');g.push(" ");g.push(' ');g.push(" ");g.push(" ");g.push(" ");g.push(" ");g.push(" ");g.push(" ");g.push(" ");g.push("
    namedata typesizedate (UTC)
    " title="Go to parent folder" class="btn_open_folder btn btn-default btn-xs">..
    ");return _.template(g.join(""))}});return{FolderListView:b}}); \ No newline at end of file diff --git a/static/scripts/packed/mvc/library/library-folderrow-view.js b/static/scripts/packed/mvc/library/library-folderrow-view.js new file mode 100644 index 00000000000..47fd065beab --- /dev/null +++ b/static/scripts/packed/mvc/library/library-folderrow-view.js @@ -0,0 +1 @@ +define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(b,d,e,c){var a=Backbone.View.extend({lastSelectedHistory:"",events:{"click .library-dataset":"showDatasetDetails"},options:{type:null},initialize:function(f){this.render(f)},render:function(f){var g=null;if(f.get("type")==="folder"){this.options.type="folder";g=this.templateRowFolder()}else{this.options.type="file";g=this.templateRowFile()}this.setElement(g({content_item:f}));this.$el.show();return this},showDatasetDetails:function(i){i.preventDefault();var j=this.id;var h=new c.Item();var g=new c.GalaxyHistories();h.id=j;var f=this;h.fetch({success:function(k){g.fetch({success:function(l){f.renderModalAfterFetch(k,l)},error:function(){e.error("An error occured during fetching histories:(");f.renderModalAfterFetch(k)}})},error:function(){e.error("An error occured during loading dataset details :(")}})},renderModalAfterFetch:function(k,h){var i=this.size_to_string(k.get("file_size"));var j=_.template(this.templateDatasetModal(),{item:k,size:i});var g=this;this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Dataset Details",body:j,buttons:{Import:function(){g.importCurrentIntoHistory()},Download:function(){g.downloadCurrent()},Close:function(){g.modal.hide()}}});$(".peek").html(k.get("peek"));if(typeof history.models!==undefined){var f=_.template(this.templateHistorySelectInModal(),{histories:h.models});$(this.modal.elMain).find(".buttons").prepend(f);if(g.lastSelectedHistory.length>0){$(this.modal.elMain).find("#dataset_import_single").val(g.lastSelectedHistory)}}},size_to_string:function(f){var g="";if(f>=100000000000){f=f/100000000000;g="TB"}else{if(f>=100000000){f=f/100000000;g="GB"}else{if(f>=100000){f=f/100000;g="MB"}else{if(f>=100){f=f/100;g="KB"}else{f=f*10;g="b"}}}}return(Math.round(f)/10)+g},downloadCurrent:function(){this.modal.disableButton("Import");this.modal.disableButton("Download");var f=[];f.push($("#id_row").attr("data-id"));var g="/api/libraries/datasets/download/uncompressed";var h={ldda_ids:f};this.processDownload(g,h);this.modal.enableButton("Import");this.modal.enableButton("Download")},processDownload:function(g,h,i){if(g&&h){h=typeof h=="string"?h:$.param(h);var f="";$.each(h.split("&"),function(){var j=this.split("=");f+=''});$('
    '+f+"
    ").appendTo("body").submit().remove();e.info("Your download will begin soon")}},importCurrentIntoHistory:function(){this.modal.disableButton("Import");this.modal.disableButton("Download");var h=$(this.modal.elMain).find("select[name=dataset_import_single] option:selected").val();this.lastSelectedHistory=h;var f=$("#id_row").attr("data-id");var i=new c.HistoryItem();var g=this;i.url=i.urlRoot+h+"/contents";i.save({content:f,source:"library"},{success:function(){e.success("Dataset imported");g.modal.enableButton("Import");g.modal.enableButton("Download")},error:function(){e.error("An error occured! Dataset not imported. Please try again.");g.modal.enableButton("Import");g.modal.enableButton("Download")}})},templateRowFolder:function(){tmpl_array=[];tmpl_array.push('');tmpl_array.push(" ");tmpl_array.push(' ');tmpl_array.push(" ");tmpl_array.push(" ");tmpl_array.push(" ");tmpl_array.push(' <%- content_item.get("name") %>');tmpl_array.push(' <% if (content_item.get("item_count") === 0) { %>');tmpl_array.push(" (empty folder)");tmpl_array.push(" <% } %>");tmpl_array.push(" ");tmpl_array.push(" folder");tmpl_array.push(' <%= _.escape(content_item.get("item_count")) %> item(s)');tmpl_array.push(' <%= _.escape(content_item.get("time_updated")) %>');tmpl_array.push("");return _.template(tmpl_array.join(""))},templateRowFile:function(){tmpl_array=[];tmpl_array.push('');tmpl_array.push(" ");tmpl_array.push(' ');tmpl_array.push(" ");tmpl_array.push(' ');tmpl_array.push(' <%- content_item.get("name") %>');tmpl_array.push(' <%= _.escape(content_item.get("data_type")) %>');tmpl_array.push(' <%= _.escape(content_item.get("readable_size")) %>');tmpl_array.push(' <%= _.escape(content_item.get("time_updated")) %>');tmpl_array.push("");return _.template(tmpl_array.join(""))},templateDatasetModal:function(){var f=[];f.push('");return f.join("")},templateHistorySelectInModal:function(){var f=[];f.push('');f.push("Select history: ");f.push('");f.push("");return f.join("")}});return{FolderRowView:a}}); \ No newline at end of file diff --git a/static/scripts/packed/mvc/library/library-foldertoolbar-view.js b/static/scripts/packed/mvc/library/library-foldertoolbar-view.js new file mode 100644 index 00000000000..b673edc51fe --- /dev/null +++ b/static/scripts/packed/mvc/library/library-foldertoolbar-view.js @@ -0,0 +1 @@ +define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(b,d,e,c){var a=Backbone.View.extend({el:"#center",events:{"click #toolbtn_create_folder":"createFolderFromModal","click #toolbtn_bulk_import":"modalBulkImport"},defaults:{can_add_library_item:false,contains_file:false},modal:null,initialize:function(f){this.options=_.defaults(f||{},this.defaults);this.render()},render:function(f){this.options=_.extend(this.options,f);var h=this.templateToolBar();var g=Galaxy.currUser.isAdmin();this.$el.html(h({id:this.options.id,admin_user:g}))},configureElements:function(f){this.options=_.extend(this.options,f);if(this.options.can_add_library_item===true){$("#toolbtn_create_folder").show();$("#toolbtn_upload_files").show()}if(this.options.contains_file===true){$("#toolbtn_bulk_import").show();$("#toolbtn_dl").show()}this.$el.find("[data-toggle]").tooltip()},createFolderFromModal:function(){event.preventDefault();event.stopPropagation();var f=this;var g=this.templateNewFolderInModal();this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Folder",body:g(),buttons:{Create:function(){f.create_new_folder_event()},Close:function(){f.modal.hide();f.modal=null}}})},create_new_folder_event:function(){var f=this.serialize_new_folder();if(this.validate_new_folder(f)){var h=new c.FolderAsModel();url_items=Backbone.history.fragment.split("/");current_folder_id=url_items[url_items.length-1];h.url=h.urlRoot+"/"+current_folder_id;var g=this;h.save(f,{success:function(i){g.modal.hide();e.success("Folder created");Galaxy.libraries.folderListView.render({id:current_folder_id})},error:function(){e.error("An error occured :(")}})}else{e.error("Folder's name is missing")}return false},serialize_new_folder:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val()}},validate_new_folder:function(f){return f.name!==""},modalBulkImport:function(){var f=$("#folder_table").find(":checked");if(f.length===0){e.info("You have to select some datasets first")}else{var h=this;var i=this.templateBulkImportInModal();var g=new c.GalaxyHistories();g.fetch({success:function(j){h.modal=Galaxy.modal;h.modal.show({closing_events:true,title:"Import into History",body:i({histories:j.models}),buttons:{Import:function(){h.importAllIntoHistory()},Close:function(){h.modal.hide()}}})},error:function(){e.error("An error occured :(")}})}},importAllIntoHistory:function(){this.modal.disableButton("Import");var h=$("select[name=dataset_import_bulk] option:selected").val();var m=$("select[name=dataset_import_bulk] option:selected").text();var o=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!==""){o.push(this.parentElement.parentElement.id)}});var n=this.templateProgressBar();$(this.modal.elMain).find(".modal-body").html(n({history_name:m}));var j=100/o.length;this.initProgress(j);var f=[];for(var g=o.length-1;g>=0;g--){library_dataset_id=o[g];var k=new c.HistoryItem();var l=this;k.url=k.urlRoot+h+"/contents";k.content=library_dataset_id;k.source="library";f.push(k)}this.chainCall(f)},chainCall:function(g){var f=this;var h=g.pop();if(typeof h==="undefined"){e.success("All datasets imported");this.modal.hide();return}var i=$.when(h.save({content:h.content,source:h.source})).done(function(j){f.updateProgress();f.chainCall(g)})},initProgress:function(f){this.progress=0;this.progressStep=f},updateProgress:function(){this.progress+=this.progressStep;$(".progress-bar-import").width(Math.round(this.progress)+"%");txt_representation=Math.round(this.progress)+"% Complete";$(".completion_span").text(txt_representation)},download:function(f,j){var h=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!==""){h.push(this.parentElement.parentElement.id)}});var g="/api/libraries/datasets/download/"+j;var i={ldda_ids:h};this.processDownload(g,i,"get")},processDownload:function(g,h,i){if(g&&h){h=typeof h=="string"?h:$.param(h);var f="";$.each(h.split("&"),function(){var j=this.split("=");f+=''});$('
    '+f+"
    ").appendTo("body").submit().remove();e.info("Your download will begin soon")}},templateToolBar:function(){tmpl_array=[];tmpl_array.push('
    ');tmpl_array.push('

    Data Libraries Beta Test. This is work in progress. Please report problems & ideas via email and Trello.

    ');tmpl_array.push('
    ');tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push(' ");tmpl_array.push("
    ");tmpl_array.push('
    ');tmpl_array.push("
    ");tmpl_array.push("
    ");return _.template(tmpl_array.join(""))},templateNewFolderInModal:function(){tmpl_array=[];tmpl_array.push('
    ');tmpl_array.push("
    ");tmpl_array.push('');tmpl_array.push('');tmpl_array.push("
    ");tmpl_array.push("
    ");return _.template(tmpl_array.join(""))},templateBulkImportInModal:function(){var f=[];f.push('');f.push("Select history: ");f.push('");f.push("");return _.template(f.join(""))},templateProgressBar:function(){var f=[];f.push('
    ');f.push("Importing selected datasets to history <%= _.escape(history_name) %>");f.push("
    ");f.push('
    ');f.push('
    ');f.push(' 0% Complete');f.push("
    ");f.push("
    ");f.push("");return _.template(f.join(""))}});return{FolderToolbarView:a}}); \ No newline at end of file diff --git a/static/scripts/packed/mvc/library/library-librarylist-view.js b/static/scripts/packed/mvc/library/library-librarylist-view.js index 3e75fd5abc6..52e4dae9cfb 100644 --- a/static/scripts/packed/mvc/library/library-librarylist-view.js +++ b/static/scripts/packed/mvc/library/library-librarylist-view.js @@ -1 +1 @@ -define(["galaxy.masthead","mvc/base-mvc","utils/utils","libs/toastr","mvc/library/library-model","mvc/library/library-libraryrow-view"],function(b,g,d,e,c,a){var f=Backbone.View.extend({el:"#libraries_element",events:{"click .sort-libraries-link":"sort_clicked"},modal:null,collection:null,rowViews:{},initialize:function(){var h=this;this.rowViews={};this.collection=new c.Libraries();this.collection.fetch({success:function(i){h.render()},error:function(j,i){e.error("An error occured. Please try again.")}})},render:function(i){var j=this.templateLibraryList();var k=null;var h=true;var h=Galaxy.libraries.preferences.get("with_deleted");var l=null;if(typeof i!=="undefined"){h=typeof i.with_deleted!=="undefined"?i.with_deleted:false;l=typeof i.models!=="undefined"?i.models:null}if(this.collection!==null&&l===null){if(h){k=this.collection.models}else{k=this.collection.where({deleted:false})}}else{if(l!==null){k=l}else{k=[]}}this.$el.html(j({length:k.length,order:Galaxy.libraries.preferences.get("sort_order")}));this.renderRows(k);$("#center [data-toggle]").tooltip();$("#center").css("overflow","auto")},renderRows:function(m){for(var l=0;lj.get("name").toLowerCase()){return 1}if(j.get("name").toLowerCase()>k.get("name").toLowerCase()){return -1}return 0}}else{if(h==="desc"){this.collection.comparator=function(k,j){if(k.get("name").toLowerCase()>j.get("name").toLowerCase()){return -1}if(j.get("name").toLowerCase()>k.get("name").toLowerCase()){return 1}return 0}}}this.collection.sort()}},templateLibraryList:function(){tmpl_array=[];tmpl_array.push('
    ');tmpl_array.push("<% if(length === 0) { %>");tmpl_array.push("
    I see no libraries. Why don't you create one?
    ");tmpl_array.push("<% } else{ %>");tmpl_array.push('');tmpl_array.push(" ");tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push(" ");tmpl_array.push(' ');tmpl_array.push(" ");tmpl_array.push("
    name descriptionsynopsis
    ");tmpl_array.push("<% }%>");tmpl_array.push("
    ");return _.template(tmpl_array.join(""))},templateNewLibraryInModal:function(){tmpl_array=[];tmpl_array.push('
    ');tmpl_array.push("
    ");tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push("
    ");tmpl_array.push("
    ");return tmpl_array.join("")},redirectToHome:function(){window.location="../"},redirectToLogin:function(){window.location="/user/login"},show_library_modal:function(i){i.preventDefault();i.stopPropagation();var h=this;this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Library",body:this.templateNewLibraryInModal(),buttons:{Create:function(){h.create_new_library_event()},Close:function(){h.modal.hide()}}})},create_new_library_event:function(){var j=this.serialize_new_library();if(this.validate_new_library(j)){var i=new c.Library();var h=this;i.save(j,{success:function(k){h.collection.add(k);h.modal.hide();h.clear_library_modal();h.render();e.success("Library created")},error:function(){e.error("An error occured :(")}})}else{e.error("Library's name is missing")}return false},clear_library_modal:function(){$("input[name='Name']").val("");$("input[name='Description']").val("");$("input[name='Synopsis']").val("")},serialize_new_library:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val(),synopsis:$("input[name='Synopsis']").val()}},validate_new_library:function(h){return h.name!==""}});return{LibraryListView:f}}); \ No newline at end of file +define(["galaxy.masthead","mvc/base-mvc","utils/utils","libs/toastr","mvc/library/library-model","mvc/library/library-libraryrow-view"],function(b,g,d,e,c,a){var f=Backbone.View.extend({el:"#libraries_element",events:{"click .sort-libraries-link":"sort_clicked"},modal:null,collection:null,rowViews:{},initialize:function(i){this.options=_.defaults(this.options||{},i);var h=this;this.rowViews={};this.collection=new c.Libraries();this.collection.fetch({success:function(j){h.render()},error:function(k,j){e.error("An error occured. Please try again.")}})},render:function(i){var j=this.templateLibraryList();var k=null;var h=Galaxy.libraries.preferences.get("with_deleted");var l=null;if(typeof i!=="undefined"){h=typeof i.with_deleted!=="undefined"?i.with_deleted:false;l=typeof i.models!=="undefined"?i.models:null}if(this.collection!==null&&l===null){if(h){k=this.collection.models}else{k=this.collection.where({deleted:false})}}else{if(l!==null){k=l}else{k=[]}}this.$el.html(j({length:k.length,order:Galaxy.libraries.preferences.get("sort_order")}));if(k.length>0){this.renderRows(k)}$("#center [data-toggle]").tooltip();$("#center").css("overflow","auto")},renderRows:function(m){for(var l=0;lj.get("name").toLowerCase()){return 1}if(j.get("name").toLowerCase()>k.get("name").toLowerCase()){return -1}return 0}}else{if(h==="desc"){this.collection.comparator=function(k,j){if(k.get("name").toLowerCase()>j.get("name").toLowerCase()){return -1}if(j.get("name").toLowerCase()>k.get("name").toLowerCase()){return 1}return 0}}}this.collection.sort()}},templateLibraryList:function(){tmpl_array=[];tmpl_array.push('
    ');tmpl_array.push("<% if(length === 0) { %>");tmpl_array.push('
    There are no libraries visible to you. If you expected some to show up please consult the library security wikipage.
    ');tmpl_array.push("<% } else{ %>");tmpl_array.push('');tmpl_array.push(" ");tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push(" ");tmpl_array.push(' ');tmpl_array.push(" ");tmpl_array.push("
    name descriptionsynopsis
    ");tmpl_array.push("<% }%>");tmpl_array.push("
    ");return _.template(tmpl_array.join(""))},templateNewLibraryInModal:function(){tmpl_array=[];tmpl_array.push('
    ');tmpl_array.push("
    ");tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push("
    ");tmpl_array.push("
    ");return tmpl_array.join("")},redirectToHome:function(){window.location="../"},redirectToLogin:function(){window.location="/user/login"},show_library_modal:function(i){i.preventDefault();i.stopPropagation();var h=this;this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Library",body:this.templateNewLibraryInModal(),buttons:{Create:function(){h.create_new_library_event()},Close:function(){h.modal.hide()}}})},create_new_library_event:function(){var j=this.serialize_new_library();if(this.validate_new_library(j)){var i=new c.Library();var h=this;i.save(j,{success:function(k){h.collection.add(k);h.modal.hide();h.clear_library_modal();h.render();e.success("Library created")},error:function(){e.error("An error occured :(")}})}else{e.error("Library's name is missing")}return false},clear_library_modal:function(){$("input[name='Name']").val("");$("input[name='Description']").val("");$("input[name='Synopsis']").val("")},serialize_new_library:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val(),synopsis:$("input[name='Synopsis']").val()}},validate_new_library:function(h){return h.name!==""}});return{LibraryListView:f}}); \ No newline at end of file diff --git a/static/scripts/packed/mvc/library/library-libraryrow-view.js b/static/scripts/packed/mvc/library/library-libraryrow-view.js index 00853bdb50c..b6572a33e35 100644 --- a/static/scripts/packed/mvc/library/library-libraryrow-view.js +++ b/static/scripts/packed/mvc/library/library-libraryrow-view.js @@ -1 +1 @@ -define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(b,d,e,c){var a=Backbone.View.extend({events:{"click .edit_library_btn":"edit_button_clicked","click .cancel_library_btn":"cancel_library_modification","click .save_library_btn":"save_library_modification","click .delete_library_btn":"delete_library","click .undelete_library_btn":"undelete_library","click .upload_library_btn":"upload_to_library","click .permission_library_btn":"permissions_on_library"},edit_mode:false,element_visibility_config:{upload_library_btn:false,edit_library_btn:false,permission_library_btn:false,save_library_btn:false,cancel_library_btn:false,delete_library_btn:false,undelete_library_btn:false},initialize:function(f){this.render(f)},render:function(g){if(typeof g==="undefined"){var g=Galaxy.libraries.libraryListView.collection.get(this.$el.data("id"))}this.prepareButtons(g);var f=this.templateRow();this.setElement(f({library:g,button_config:this.element_visibility_config,edit_mode:this.edit_mode}));this.$el.show();return this},repaint:function(f){$(".tooltip").hide();var g=this.$el;this.render(f);g.replaceWith(this.$el);this.$el.find("[data-toggle]").tooltip()},prepareButtons:function(f){vis_config=this.element_visibility_config;if(this.edit_mode===false){vis_config.save_library_btn=false;vis_config.cancel_library_btn=false;vis_config.delete_library_btn=false;if(f.get("deleted")===true){vis_config.undelete_library_btn=true;vis_config.upload_library_btn=false;vis_config.edit_library_btn=false;vis_config.permission_library_btn=false}else{if(f.get("deleted")===false){vis_config.save_library_btn=false;vis_config.cancel_library_btn=false;vis_config.undelete_library_btn=false;if(f.get("can_user_add")===true){vis_config.upload_library_btn=true}if(f.get("can_user_modify")===true){vis_config.edit_library_btn=true}if(f.get("can_user_manage")===true){vis_config.permission_library_btn=true}}}}else{if(this.edit_mode===true){vis_config.upload_library_btn=false;vis_config.edit_library_btn=false;vis_config.permission_library_btn=false;vis_config.save_library_btn=true;vis_config.cancel_library_btn=true;vis_config.delete_library_btn=true}}this.element_visibility_config=vis_config},upload_to_library:function(){e.info("Coming soon. Stay tuned.")},permissions_on_library:function(){e.info("Coming soon. Stay tuned.")},edit_button_clicked:function(){this.edit_mode=true;this.repaint()},cancel_library_modification:function(){e.info("Modifications canceled");this.edit_mode=false;this.repaint()},save_library_modification:function(){var g=Galaxy.libraries.libraryListView.collection.get(this.$el.data("id"));var h=false;var j=this.$el.find(".input_library_name").val();if(typeof j!=="undefined"&&j!==g.get("name")){if(j.length>2){g.set("name",j);h=true}else{e.warning("Library name has to be at least 3 characters long");return}}var i=this.$el.find(".input_library_description").val();if(typeof i!=="undefined"&&i!==g.get("description")){g.set("description",i);h=true}var k=this.$el.find(".input_library_synopsis").val();if(typeof k!=="undefined"&&k!==g.get("synopsis")){g.set("synopsis",k);h=true}if(h){var f=this;g.save(null,{patch:true,success:function(l){f.edit_mode=false;f.repaint(l);e.success("Changes to library saved")},error:function(m,l){e.error("An error occured during updating the library :(")}})}else{this.edit_mode=false;this.repaint(g);e.info("Nothing has changed")}},delete_library:function(){var g=Galaxy.libraries.libraryListView.collection.get(this.$el.data("id"));var f=this;g.destroy({success:function(h){h.set("deleted",true);Galaxy.libraries.libraryListView.collection.add(h);f.edit_mode=false;if(Galaxy.libraries.preferences.get("with_deleted")===false){$(".tooltip").hide();f.$el.remove()}else{if(Galaxy.libraries.preferences.get("with_deleted")===true){f.repaint(h)}}e.success("Library has been marked deleted")},error:function(){e.error("An error occured during deleting the library :(")}})},undelete_library:function(){var g=Galaxy.libraries.libraryListView.collection.get(this.$el.data("id"));var f=this;g.url=g.urlRoot+g.id+"?undelete=true";g.destroy({success:function(h){h.set("deleted",false);Galaxy.libraries.libraryListView.collection.add(h);f.edit_mode=false;f.repaint(h);e.success("Library has been undeleted")},error:function(){e.error("An error occured while undeleting the library :(")}})},templateRow:function(){tmpl_array=[];tmpl_array.push(' " style="display:none;" data-id="<%- library.get("id") %>">');tmpl_array.push(" <% if(!edit_mode) { %>");tmpl_array.push(' "><%- library.get("name") %>');tmpl_array.push(' <%= _.escape(library.get("description")) %>');tmpl_array.push(' <%= _.escape(library.get("synopsis")) %>');tmpl_array.push(" <% } else if(edit_mode){ %>");tmpl_array.push(' ">');tmpl_array.push(' ">');tmpl_array.push(' ">');tmpl_array.push(" <% } %>");tmpl_array.push(' ');tmpl_array.push(' <% if(library.get("deleted") === true) { %>');tmpl_array.push(' ');tmpl_array.push(' <% } else if(library.get("public") === true) { %>');tmpl_array.push(' ');tmpl_array.push(" <% }%>");tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push(" ");tmpl_array.push(" ");return _.template(tmpl_array.join(""))}});return{LibraryRowView:a}}); \ No newline at end of file +define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(b,d,e,c){var a=Backbone.View.extend({events:{"click .edit_library_btn":"edit_button_clicked","click .cancel_library_btn":"cancel_library_modification","click .save_library_btn":"save_library_modification","click .delete_library_btn":"delete_library","click .undelete_library_btn":"undelete_library","click .upload_library_btn":"upload_to_library","click .permission_library_btn":"permissions_on_library"},edit_mode:false,element_visibility_config:{upload_library_btn:false,edit_library_btn:false,permission_library_btn:false,save_library_btn:false,cancel_library_btn:false,delete_library_btn:false,undelete_library_btn:false},initialize:function(f){this.render(f)},render:function(g){if(typeof g==="undefined"){g=Galaxy.libraries.libraryListView.collection.get(this.$el.data("id"))}this.prepareButtons(g);var f=this.templateRow();this.setElement(f({library:g,button_config:this.element_visibility_config,edit_mode:this.edit_mode}));this.$el.show();return this},repaint:function(f){$(".tooltip").hide();var g=this.$el;this.render(f);g.replaceWith(this.$el);this.$el.find("[data-toggle]").tooltip()},prepareButtons:function(f){vis_config=this.element_visibility_config;if(this.edit_mode===false){vis_config.save_library_btn=false;vis_config.cancel_library_btn=false;vis_config.delete_library_btn=false;if(f.get("deleted")===true){vis_config.undelete_library_btn=true;vis_config.upload_library_btn=false;vis_config.edit_library_btn=false;vis_config.permission_library_btn=false}else{if(f.get("deleted")===false){vis_config.save_library_btn=false;vis_config.cancel_library_btn=false;vis_config.undelete_library_btn=false;if(f.get("can_user_add")===true){vis_config.upload_library_btn=true}if(f.get("can_user_modify")===true){vis_config.edit_library_btn=true}if(f.get("can_user_manage")===true){vis_config.permission_library_btn=true}}}}else{if(this.edit_mode===true){vis_config.upload_library_btn=false;vis_config.edit_library_btn=false;vis_config.permission_library_btn=false;vis_config.save_library_btn=true;vis_config.cancel_library_btn=true;vis_config.delete_library_btn=true}}this.element_visibility_config=vis_config},upload_to_library:function(){e.info("Coming soon. Stay tuned.")},permissions_on_library:function(){e.info("Coming soon. Stay tuned.")},edit_button_clicked:function(){this.edit_mode=true;this.repaint()},cancel_library_modification:function(){e.info("Modifications canceled");this.edit_mode=false;this.repaint()},save_library_modification:function(){var g=Galaxy.libraries.libraryListView.collection.get(this.$el.data("id"));var h=false;var j=this.$el.find(".input_library_name").val();if(typeof j!=="undefined"&&j!==g.get("name")){if(j.length>2){g.set("name",j);h=true}else{e.warning("Library name has to be at least 3 characters long");return}}var i=this.$el.find(".input_library_description").val();if(typeof i!=="undefined"&&i!==g.get("description")){g.set("description",i);h=true}var k=this.$el.find(".input_library_synopsis").val();if(typeof k!=="undefined"&&k!==g.get("synopsis")){g.set("synopsis",k);h=true}if(h){var f=this;g.save(null,{patch:true,success:function(l){f.edit_mode=false;f.repaint(l);e.success("Changes to library saved")},error:function(m,l){e.error("An error occured during updating the library :(")}})}else{this.edit_mode=false;this.repaint(g);e.info("Nothing has changed")}},delete_library:function(){var g=Galaxy.libraries.libraryListView.collection.get(this.$el.data("id"));var f=this;g.destroy({success:function(h){h.set("deleted",true);Galaxy.libraries.libraryListView.collection.add(h);f.edit_mode=false;if(Galaxy.libraries.preferences.get("with_deleted")===false){$(".tooltip").hide();f.$el.remove()}else{if(Galaxy.libraries.preferences.get("with_deleted")===true){f.repaint(h)}}e.success("Library has been marked deleted")},error:function(){e.error("An error occured during deleting the library :(")}})},undelete_library:function(){var g=Galaxy.libraries.libraryListView.collection.get(this.$el.data("id"));var f=this;g.url=g.urlRoot+g.id+"?undelete=true";g.destroy({success:function(h){h.set("deleted",false);Galaxy.libraries.libraryListView.collection.add(h);f.edit_mode=false;f.repaint(h);e.success("Library has been undeleted")},error:function(){e.error("An error occured while undeleting the library :(")}})},templateRow:function(){tmpl_array=[];tmpl_array.push(' " style="display:none;" data-id="<%- library.get("id") %>">');tmpl_array.push(" <% if(!edit_mode) { %>");tmpl_array.push(' "><%- library.get("name") %>');tmpl_array.push(' <%= _.escape(library.get("description")) %>');tmpl_array.push(' <%= _.escape(library.get("synopsis")) %>');tmpl_array.push(" <% } else if(edit_mode){ %>");tmpl_array.push(' ">');tmpl_array.push(' ">');tmpl_array.push(' ">');tmpl_array.push(" <% } %>");tmpl_array.push(' ');tmpl_array.push(' <% if(library.get("deleted") === true) { %>');tmpl_array.push(' ');tmpl_array.push(' <% } else if(library.get("public") === true) { %>');tmpl_array.push(' ');tmpl_array.push(" <% }%>");tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push(" ");tmpl_array.push(" ");return _.template(tmpl_array.join(""))}});return{LibraryRowView:a}}); \ No newline at end of file diff --git a/static/scripts/packed/mvc/library/library-librarytoolbar-view.js b/static/scripts/packed/mvc/library/library-librarytoolbar-view.js index 64acfd29113..6369a270cc9 100644 --- a/static/scripts/packed/mvc/library/library-librarytoolbar-view.js +++ b/static/scripts/packed/mvc/library/library-librarytoolbar-view.js @@ -1 +1 @@ -define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(a,d,e,c){var b=Backbone.View.extend({el:"#center",events:{"click #create_new_library_btn":"delegate_modal","click #include_deleted_chk":"check_include_deleted"},initialize:function(){this.render()},render:function(){var f=this.templateToolBar();this.$el.html(f({admin_user:Galaxy.currUser.isAdmin(),anon_user:Galaxy.currUser.isAnonymous()}));if(Galaxy.currUser.isAdmin()===true){this.$el.find("#include_deleted_chk")[0].checked=Galaxy.libraries.preferences.get("with_deleted")}},delegate_modal:function(f){Galaxy.libraries.libraryListView.show_library_modal(f)},check_include_deleted:function(f){if(f.target.checked){Galaxy.libraries.preferences.set({with_deleted:true});Galaxy.libraries.libraryListView.render()}else{Galaxy.libraries.preferences.set({with_deleted:false});Galaxy.libraries.libraryListView.render()}},templateToolBar:function(){tmpl_array=[];tmpl_array.push('
    ');tmpl_array.push('
    ');tmpl_array.push('

    Data Libraries Beta Test. This is work in progress. Please report problems & ideas via email and Trello.

    ');tmpl_array.push(" <% if(admin_user === true) { %>");tmpl_array.push('
    ');tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push("
    ");tmpl_array.push(" <% } %>");tmpl_array.push("
    ");tmpl_array.push('
    ');tmpl_array.push("
    ");tmpl_array.push("
    ");return _.template(tmpl_array.join(""))}});return{ToolbarView:b}}); \ No newline at end of file +define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(a,c,d,b){var e=Backbone.View.extend({el:"#center",events:{"click #create_new_library_btn":"delegate_modal","click #include_deleted_chk":"check_include_deleted"},initialize:function(){this.render()},render:function(){var h=this.templateToolBar();var g=Galaxy.currUser.isAdmin();var f=Galaxy.currUser.isAnonymous();this.$el.html(h({admin_user:g,anon_user:f}));if(Galaxy.currUser.isAdmin()===true){this.$el.find("#include_deleted_chk")[0].checked=Galaxy.libraries.preferences.get("with_deleted")}},delegate_modal:function(f){Galaxy.libraries.libraryListView.show_library_modal(f)},check_include_deleted:function(f){if(f.target.checked){Galaxy.libraries.preferences.set({with_deleted:true});Galaxy.libraries.libraryListView.render()}else{Galaxy.libraries.preferences.set({with_deleted:false});Galaxy.libraries.libraryListView.render()}},templateToolBar:function(){tmpl_array=[];tmpl_array.push('
    ');tmpl_array.push('
    ');tmpl_array.push('

    Data Libraries Beta Test. This is work in progress. Please report problems & ideas via email and Trello.

    ');tmpl_array.push(" <% if(admin_user === true) { %>");tmpl_array.push('
    ');tmpl_array.push(' ');tmpl_array.push(' ');tmpl_array.push("
    ");tmpl_array.push(" <% } %>");tmpl_array.push("
    ");tmpl_array.push('
    ');tmpl_array.push("
    ");tmpl_array.push("
    ");return _.template(tmpl_array.join(""))}});return{LibraryToolbarView:e}}); \ No newline at end of file diff --git a/static/scripts/packed/mvc/library/library-model.js b/static/scripts/packed/mvc/library/library-model.js index bd1d114f95e..a752fc3d196 100644 --- a/static/scripts/packed/mvc/library/library-model.js +++ b/static/scripts/packed/mvc/library/library-model.js @@ -1 +1 @@ -define([],function(){var e=Backbone.Model.extend({urlRoot:"/api/libraries/",isVisible:function(k){var j=true;if((!show_delete)&&(this.get("deleted"))){j=false}return j}});var a=Backbone.Model.extend({urlRoot:"/api/folders"});var h=Backbone.Collection.extend({url:"/api/libraries",model:e,sort_key:"name",sort_order:null,initialize:function(j){j=j||{}},getVisible:function(k,l){l=l||[];var j=new h(this.filter(function(m){return m.isVisible(k)}));return j}});var f=Backbone.Model.extend({urlRoot:"/api/libraries/datasets"});var c=Backbone.Collection.extend({model:f});var d=Backbone.Model.extend({defaults:{folder:new c(),full_path:"unknown",urlRoot:"/api/folders/",id:"unknown"},parse:function(j){this.full_path=j[0].full_path;this.get("folder").reset(j[1].folder_contents);return j}});var b=Backbone.Model.extend({urlRoot:"/api/histories/"});var g=Backbone.Model.extend({url:"/api/histories/"});var i=Backbone.Collection.extend({url:"/api/histories",model:g});return{Library:e,FolderAsModel:a,Libraries:h,Item:f,Folder:c,FolderContainer:d,HistoryItem:b,GalaxyHistory:g,GalaxyHistories:i}}); \ No newline at end of file +define([],function(){var e=Backbone.Model.extend({urlRoot:"/api/libraries/",isVisible:function(k){var j=true;if((!show_delete)&&(this.get("deleted"))){j=false}return j}});var a=Backbone.Model.extend({urlRoot:"/api/folders"});var h=Backbone.Collection.extend({url:"/api/libraries",model:e,sort_key:"name",sort_order:null,initialize:function(j){j=j||{}},getVisible:function(k,l){l=l||[];var j=new h(this.filter(function(m){return m.isVisible(k)}));return j}});var f=Backbone.Model.extend({urlRoot:"/api/libraries/datasets"});var c=Backbone.Collection.extend({model:f});var d=Backbone.Model.extend({defaults:{folder:new c(),urlRoot:"/api/folders/",id:"unknown"},parse:function(j){this.get("folder").reset(j.folder_contents);return j}});var b=Backbone.Model.extend({urlRoot:"/api/histories/"});var g=Backbone.Model.extend({url:"/api/histories/"});var i=Backbone.Collection.extend({url:"/api/histories",model:g});return{Library:e,FolderAsModel:a,Libraries:h,Item:f,Folder:c,FolderContainer:d,HistoryItem:b,GalaxyHistory:g,GalaxyHistories:i}}); \ No newline at end of file diff --git a/static/scripts/packed/mvc/tools.js b/static/scripts/packed/mvc/tools.js index 59425c1054c..07c273e927b 100644 --- a/static/scripts/packed/mvc/tools.js +++ b/static/scripts/packed/mvc/tools.js @@ -1 +1 @@ -define(["libs/underscore","viz/trackster/util","mvc/data"],function(x,a,y){var g={hidden:false,show:function(){this.set("hidden",false)},hide:function(){this.set("hidden",true)},toggle:function(){this.set("hidden",!this.get("hidden"))},is_visible:function(){return !this.attributes.hidden}};var e=Backbone.Model.extend({defaults:{name:null,label:null,type:null,value:null,html:null,num_samples:5},initialize:function(){this.attributes.html=unescape(this.attributes.html)},copy:function(){return new e(this.toJSON())},set_value:function(z){this.set("value",z||"")}});var i=Backbone.Collection.extend({model:e});var k=e.extend({});var d=e.extend({set_value:function(z){this.set("value",parseInt(z,10))},get_samples:function(){return d3.scale.linear().domain([this.get("min"),this.get("max")]).ticks(this.get("num_samples"))}});var f=d.extend({set_value:function(z){this.set("value",parseFloat(z))}});var t=e.extend({get_samples:function(){return x.map(this.get("options"),function(z){return z[0]})}});e.subModelTypes={integer:d,"float":f,data:k,select:t};var j=Backbone.Model.extend({defaults:{id:null,name:null,description:null,target:null,inputs:[],outputs:[]},initialize:function(z){this.set("inputs",new i(x.map(z.inputs,function(A){var B=e.subModelTypes[A.type]||e;return new B(A)})))},urlRoot:galaxy_config.root+"api/tools",remove_inputs:function(A){var z=this,B=z.get("inputs").filter(function(C){return(A.indexOf(C.get("type"))!==-1)});z.get("inputs").remove(B)},copy:function(A){var B=new j(this.toJSON());if(A){var z=new Backbone.Collection();B.get("inputs").each(function(C){if(C.get_samples()){z.push(C)}});B.set("inputs",z)}return B},apply_search_results:function(z){(x.indexOf(z,this.attributes.id)!==-1?this.show():this.hide());return this.is_visible()},set_input_value:function(z,A){this.get("inputs").find(function(B){return B.get("name")===z}).set("value",A)},set_input_values:function(A){var z=this;x.each(x.keys(A),function(B){z.set_input_value(B,A[B])})},run:function(){return this._run()},rerun:function(A,z){return this._run({action:"rerun",target_dataset_id:A.id,regions:z})},get_inputs_dict:function(){var z={};this.get("inputs").each(function(A){z[A.get("name")]=A.get("value")});return z},_run:function(B){var C=x.extend({tool_id:this.id,inputs:this.get_inputs_dict()},B);var A=$.Deferred(),z=new a.ServerStateDeferred({ajax_settings:{url:this.urlRoot,data:JSON.stringify(C),dataType:"json",contentType:"application/json",type:"POST"},interval:2000,success_fn:function(D){return D!=="pending"}});$.when(z.go()).then(function(D){A.resolve(new y.DatasetCollection().reset(D))});return A}});x.extend(j.prototype,g);var q=Backbone.View.extend({});var n=Backbone.Collection.extend({model:j});var v=Backbone.Model.extend(g);var l=Backbone.Model.extend({defaults:{elems:[],open:false},clear_search_results:function(){x.each(this.attributes.elems,function(z){z.show()});this.show();this.set("open",false)},apply_search_results:function(A){var B=true,z;x.each(this.attributes.elems,function(C){if(C instanceof v){z=C;z.hide()}else{if(C instanceof j){if(C.apply_search_results(A)){B=false;if(z){z.show()}}}}});if(B){this.hide()}else{this.show();this.set("open",true)}}});x.extend(l.prototype,g);var c=Backbone.Model.extend({defaults:{search_hint_string:"search tools",min_chars_for_search:3,spinner_url:"",clear_btn_url:"",search_url:"",visible:true,query:"",results:null,clear_key:27},initialize:function(){this.on("change:query",this.do_search)},do_search:function(){var B=this.attributes.query;if(B.length").text(this.model.attributes.text));return this}});var r=s.extend({tagName:"div",className:"toolSectionWrapper",initialize:function(){s.prototype.initialize.call(this);this.model.on("change:open",this.update_open,this)},render:function(){this.$el.append(Handlebars.templates.panel_section(this.model.toJSON()));var z=this.$el.find(".toolSectionBody");x.each(this.model.attributes.elems,function(A){if(A instanceof j){var B=new m({model:A,className:"toolTitle"});B.render();z.append(B.$el)}else{if(A instanceof v){var C=new b({model:A});C.render();z.append(C.$el)}else{}}});return this},events:{"click .toolSectionTitle > a":"toggle"},toggle:function(){this.model.set("open",!this.model.attributes.open)},update_open:function(){(this.model.attributes.open?this.$el.children(".toolSectionBody").slideDown("fast"):this.$el.children(".toolSectionBody").slideUp("fast"))}});var p=Backbone.View.extend({tagName:"div",id:"tool-search",className:"bar",events:{click:"focus_and_select","keyup :input":"query_changed","click #search-clear-btn":"clear"},render:function(){this.$el.append(Handlebars.templates.tool_search(this.model.toJSON()));if(!this.model.is_visible()){this.$el.hide()}this.$el.find("[title]").tooltip();return this},focus_and_select:function(){this.$el.find(":input").focus().select()},clear:function(){this.model.clear_search();this.$el.find(":input").val(this.model.attributes.search_hint_string);this.focus_and_select();return false},query_changed:function(z){if((this.model.attributes.clear_key)&&(this.model.attributes.clear_key===z.which)){this.clear();return false}this.model.set("query",this.$el.find(":input").val())}});var w=Backbone.View.extend({tagName:"div",className:"toolMenu",initialize:function(){this.model.get("tool_search").on("change:results",this.handle_search_results,this)},render:function(){var z=this;var A=new p({model:this.model.get("tool_search")});A.render();z.$el.append(A.$el);this.model.get("layout").each(function(C){if(C instanceof l){var B=new r({model:C});B.render();z.$el.append(B.$el)}else{if(C instanceof j){var D=new m({model:C,className:"toolTitleNoSection"});D.render();z.$el.append(D.$el)}else{if(C instanceof v){var E=new b({model:C});E.render();z.$el.append(E.$el)}}}});z.$el.find("a.tool-link").click(function(D){var C=$(this).attr("class").split(/\s+/)[0],B=z.model.get("tools").get(C);z.trigger("tool_link_click",D,B)});return this},handle_search_results:function(){var z=this.model.get("tool_search").get("results");if(z&&z.length===0){$("#search-no-results").show()}else{$("#search-no-results").hide()}}});var u=Backbone.View.extend({className:"toolForm",render:function(){this.$el.children().remove();this.$el.append(Handlebars.templates.tool_form(this.model.toJSON()))}});var h=Backbone.View.extend({className:"toolMenuAndView",initialize:function(){this.tool_panel_view=new w({collection:this.collection});this.tool_form_view=new u()},render:function(){this.tool_panel_view.render();this.tool_panel_view.$el.css("float","left");this.$el.append(this.tool_panel_view.$el);this.tool_form_view.$el.hide();this.$el.append(this.tool_form_view.$el);var z=this;this.tool_panel_view.on("tool_link_click",function(B,A){B.preventDefault();z.show_tool(A)})},show_tool:function(A){var z=this;A.fetch().done(function(){z.tool_form_view.model=A;z.tool_form_view.render();z.tool_form_view.$el.show();$("#left").width("650px")})}});return{ToolParameter:e,IntegerToolParameter:d,SelectToolParameter:t,Tool:j,ToolCollection:n,ToolSearch:c,ToolPanel:o,ToolPanelView:w,ToolFormView:u}}); \ No newline at end of file +define(["libs/underscore","viz/trackster/util","mvc/data"],function(x,a,y){var g={hidden:false,show:function(){this.set("hidden",false)},hide:function(){this.set("hidden",true)},toggle:function(){this.set("hidden",!this.get("hidden"))},is_visible:function(){return !this.attributes.hidden}};var e=Backbone.Model.extend({defaults:{name:null,label:null,type:null,value:null,html:null,num_samples:5},initialize:function(z){this.attributes.html=unescape(this.attributes.html)},copy:function(){return new e(this.toJSON())},set_value:function(z){this.set("value",z||"")}});var i=Backbone.Collection.extend({model:e});var k=e.extend({});var d=e.extend({set_value:function(z){this.set("value",parseInt(z,10))},get_samples:function(){return d3.scale.linear().domain([this.get("min"),this.get("max")]).ticks(this.get("num_samples"))}});var f=d.extend({set_value:function(z){this.set("value",parseFloat(z))}});var t=e.extend({get_samples:function(){return x.map(this.get("options"),function(z){return z[0]})}});e.subModelTypes={integer:d,"float":f,data:k,select:t};var j=Backbone.Model.extend({defaults:{id:null,name:null,description:null,target:null,inputs:[],outputs:[]},urlRoot:galaxy_config.root+"api/tools",initialize:function(z){this.set("inputs",new i(x.map(z.inputs,function(A){var B=e.subModelTypes[A.type]||e;return new B(A)})))},toJSON:function(){var z=Backbone.Model.prototype.toJSON.call(this);z.inputs=this.get("inputs").map(function(A){return A.toJSON()});return z},remove_inputs:function(A){var z=this,B=z.get("inputs").filter(function(C){return(A.indexOf(C.get("type"))!==-1)});z.get("inputs").remove(B)},copy:function(A){var B=new j(this.toJSON());if(A){var z=new Backbone.Collection();B.get("inputs").each(function(C){if(C.get_samples()){z.push(C)}});B.set("inputs",z)}return B},apply_search_results:function(z){(x.indexOf(z,this.attributes.id)!==-1?this.show():this.hide());return this.is_visible()},set_input_value:function(z,A){this.get("inputs").find(function(B){return B.get("name")===z}).set("value",A)},set_input_values:function(A){var z=this;x.each(x.keys(A),function(B){z.set_input_value(B,A[B])})},run:function(){return this._run()},rerun:function(A,z){return this._run({action:"rerun",target_dataset_id:A.id,regions:z})},get_inputs_dict:function(){var z={};this.get("inputs").each(function(A){z[A.get("name")]=A.get("value")});return z},_run:function(B){var C=x.extend({tool_id:this.id,inputs:this.get_inputs_dict()},B);var A=$.Deferred(),z=new a.ServerStateDeferred({ajax_settings:{url:this.urlRoot,data:JSON.stringify(C),dataType:"json",contentType:"application/json",type:"POST"},interval:2000,success_fn:function(D){return D!=="pending"}});$.when(z.go()).then(function(D){A.resolve(new y.DatasetCollection().reset(D))});return A}});x.extend(j.prototype,g);var q=Backbone.View.extend({});var n=Backbone.Collection.extend({model:j});var v=Backbone.Model.extend(g);var l=Backbone.Model.extend({defaults:{elems:[],open:false},clear_search_results:function(){x.each(this.attributes.elems,function(z){z.show()});this.show();this.set("open",false)},apply_search_results:function(A){var B=true,z;x.each(this.attributes.elems,function(C){if(C instanceof v){z=C;z.hide()}else{if(C instanceof j){if(C.apply_search_results(A)){B=false;if(z){z.show()}}}}});if(B){this.hide()}else{this.show();this.set("open",true)}}});x.extend(l.prototype,g);var c=Backbone.Model.extend({defaults:{search_hint_string:"search tools",min_chars_for_search:3,spinner_url:"",clear_btn_url:"",search_url:"",visible:true,query:"",results:null,clear_key:27},initialize:function(){this.on("change:query",this.do_search)},do_search:function(){var B=this.attributes.query;if(B.length").text(this.model.attributes.text));return this}});var r=s.extend({tagName:"div",className:"toolSectionWrapper",initialize:function(){s.prototype.initialize.call(this);this.model.on("change:open",this.update_open,this)},render:function(){this.$el.append(Handlebars.templates.panel_section(this.model.toJSON()));var z=this.$el.find(".toolSectionBody");x.each(this.model.attributes.elems,function(A){if(A instanceof j){var B=new m({model:A,className:"toolTitle"});B.render();z.append(B.$el)}else{if(A instanceof v){var C=new b({model:A});C.render();z.append(C.$el)}else{}}});return this},events:{"click .toolSectionTitle > a":"toggle"},toggle:function(){this.model.set("open",!this.model.attributes.open)},update_open:function(){(this.model.attributes.open?this.$el.children(".toolSectionBody").slideDown("fast"):this.$el.children(".toolSectionBody").slideUp("fast"))}});var p=Backbone.View.extend({tagName:"div",id:"tool-search",className:"bar",events:{click:"focus_and_select","keyup :input":"query_changed","click #search-clear-btn":"clear"},render:function(){this.$el.append(Handlebars.templates.tool_search(this.model.toJSON()));if(!this.model.is_visible()){this.$el.hide()}this.$el.find("[title]").tooltip();return this},focus_and_select:function(){this.$el.find(":input").focus().select()},clear:function(){this.model.clear_search();this.$el.find(":input").val(this.model.attributes.search_hint_string);this.focus_and_select();return false},query_changed:function(z){if((this.model.attributes.clear_key)&&(this.model.attributes.clear_key===z.which)){this.clear();return false}this.model.set("query",this.$el.find(":input").val())}});var w=Backbone.View.extend({tagName:"div",className:"toolMenu",initialize:function(){this.model.get("tool_search").on("change:results",this.handle_search_results,this)},render:function(){var z=this;var A=new p({model:this.model.get("tool_search")});A.render();z.$el.append(A.$el);this.model.get("layout").each(function(C){if(C instanceof l){var B=new r({model:C});B.render();z.$el.append(B.$el)}else{if(C instanceof j){var D=new m({model:C,className:"toolTitleNoSection"});D.render();z.$el.append(D.$el)}else{if(C instanceof v){var E=new b({model:C});E.render();z.$el.append(E.$el)}}}});z.$el.find("a.tool-link").click(function(D){var C=$(this).attr("class").split(/\s+/)[0],B=z.model.get("tools").get(C);z.trigger("tool_link_click",D,B)});return this},handle_search_results:function(){var z=this.model.get("tool_search").get("results");if(z&&z.length===0){$("#search-no-results").show()}else{$("#search-no-results").hide()}}});var u=Backbone.View.extend({className:"toolForm",render:function(){this.$el.children().remove();this.$el.append(Handlebars.templates.tool_form(this.model.toJSON()))}});var h=Backbone.View.extend({className:"toolMenuAndView",initialize:function(){this.tool_panel_view=new w({collection:this.collection});this.tool_form_view=new u()},render:function(){this.tool_panel_view.render();this.tool_panel_view.$el.css("float","left");this.$el.append(this.tool_panel_view.$el);this.tool_form_view.$el.hide();this.$el.append(this.tool_form_view.$el);var z=this;this.tool_panel_view.on("tool_link_click",function(B,A){B.preventDefault();z.show_tool(A)})},show_tool:function(A){var z=this;A.fetch().done(function(){z.tool_form_view.model=A;z.tool_form_view.render();z.tool_form_view.$el.show();$("#left").width("650px")})}});return{ToolParameter:e,IntegerToolParameter:d,SelectToolParameter:t,Tool:j,ToolCollection:n,ToolSearch:c,ToolPanel:o,ToolPanelView:w,ToolFormView:u}}); \ No newline at end of file diff --git a/static/scripts/packed/utils/config.js b/static/scripts/packed/utils/config.js index e2a3158c482..628535f4948 100644 --- a/static/scripts/packed/utils/config.js +++ b/static/scripts/packed/utils/config.js @@ -1 +1 @@ -define(["libs/underscore","viz/trackster/util","utils/config"],function(c,f,b){var d=Backbone.Model.extend({initialize:function(g){var h=this.get("key");this.set("id",h);var i=c.find(d.known_settings_defaults,function(j){return j.key===h});if(i){this.set(c.extend({},i,g))}if(this.get("value")===undefined){this.set_value(this.get("default_value"));if(!this.get("value")&&this.get("type")==="color"){this.set("value",f.get_random_color())}}},set_value:function(h){var g=this.get("type");if(g==="float"){h=parseFloat(h)}else{if(g==="int"){h=parseInt(h,10)}}this.set("value",h)}},{known_settings_defaults:[{key:"name",label:"Name",type:"text",default_value:""},{key:"color",label:"Color",type:"color",default_value:null},{key:"min_value",label:"Min Value",type:"float",default_value:null},{key:"max_value",label:"Max Value",type:"float",default_value:null},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:32,hidden:true},{key:"pos_color",label:"Positive Color",type:"color",default_value:"#FF8C00"},{key:"neg_color",label:"Negative Color",type:"color",default_value:"#4169E1"},{key:"block_color",label:"Block color",type:"color",default_value:null},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"reverse_strand_color",label:"Antisense strand color",type:"color",default_value:null},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true}]});var e=Backbone.Collection.extend({model:d,to_key_value_dict:function(){var g={};this.each(function(h){g[h.get("key")]=h.get("value")});return g},get_value:function(g){var h=this.get(g);if(h){return h.get("value")}return undefined},set_value:function(g,i){var h=this.get(g);if(h){return h.set_value(i)}return undefined},set_default_value:function(h,g){var i=this.get(h);if(i){return i.set("default_value",g)}return undefined}},{from_models_and_saved_values:function(h,g){if(g){h=c.map(h,function(i){return c.extend({},i,{value:g[i.key]})})}return new e(h)}});var a=Backbone.View.extend({className:"config-settings-view",render:function(){var g=this.$el;this.collection.each(function(j,n){if(j.get("hidden")){return}var i="param_"+n,o=j.get("type"),s=j.get("value");var t=$("
    ").appendTo(g);t.append($("