commit/galaxy-central: greg: Add a new HgWebConfigManager to manage the tool shed's hgweb.config file.
1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/changeset/d3ac39a6f8d7/ changeset: d3ac39a6f8d7 user: greg date: 2012-11-13 18:04:58 summary: Add a new HgWebConfigManager to manage the tool shed's hgweb.config file. affected #: 8 files diff -r 3024a86c0d0d21b1a85ff1b91516f34f416bcfcb -r d3ac39a6f8d7a5f95ffabb4ba8f8a846b17ac15a lib/galaxy/util/shed_util.py --- a/lib/galaxy/util/shed_util.py +++ b/lib/galaxy/util/shed_util.py @@ -118,6 +118,7 @@ self.workflows += 1 processed_relative_workflow_paths.append( relative_path ) self.generation_time = strftime( "%b %d, %Y", gmtime() ) + def add_to_shed_tool_config( app, shed_tool_conf_dict, elem_list ): # A tool shed repository is being installed so change the shed_tool_conf file. Parse the config file to generate the entire list # of config_elems instead of using the in-memory list since it will be a subset of the entire list if one or more repositories have @@ -1353,11 +1354,6 @@ ctx = get_changectx_for_changeset( repo, changeset_revision ) named_tmp_file = get_named_tmpfile_from_ctx( ctx, file_name, dir ) return named_tmp_file -def get_hgweb_config( app ): - hgweb_config = os.path.join( app.config.hgweb_config_dir, 'hgweb.config' ) - if not os.path.exists( hgweb_config ): - raise Exception( "Required file %s does not exist - check config setting for hgweb_config_dir." % hgweb_config ) - return hgweb_config def get_installed_tool_shed_repository( trans, id ): """Get a repository on the Galaxy side from the database via id""" return trans.sa_session.query( trans.model.ToolShedRepository ).get( trans.security.decode_id( id ) ) diff -r 3024a86c0d0d21b1a85ff1b91516f34f416bcfcb -r d3ac39a6f8d7a5f95ffabb4ba8f8a846b17ac15a lib/galaxy/webapps/community/app.py --- a/lib/galaxy/webapps/community/app.py +++ b/lib/galaxy/webapps/community/app.py @@ -46,5 +46,8 @@ # TODO: Add OpenID support self.openid_providers = OpenIDProviders() self.shed_counter = self.model.shed_counter + # Let the HgwebConfigManager know where the hgweb.config file is located. + self.hgweb_config_manager = self.model.hgweb_config_manager + self.hgweb_config_manager.hgweb_config_dir = self.config.hgweb_config_dir def shutdown( self ): pass diff -r 3024a86c0d0d21b1a85ff1b91516f34f416bcfcb -r d3ac39a6f8d7a5f95ffabb4ba8f8a846b17ac15a lib/galaxy/webapps/community/controllers/hg.py --- a/lib/galaxy/webapps/community/controllers/hg.py +++ b/lib/galaxy/webapps/community/controllers/hg.py @@ -1,7 +1,6 @@ import os, logging from galaxy.web.base.controller import * from galaxy.webapps.community.controllers.common import * -from galaxy.util.shed_util import get_hgweb_config from galaxy import eggs eggs.require('mercurial') @@ -18,9 +17,7 @@ # hg clone http://test@127.0.0.1:9009/repos/test/convert_characters1 hg_version = mercurial.__version__.version cmd = kwd.get( 'cmd', None ) - hgweb_config = get_hgweb_config( trans.app ) - if not os.path.exists( hgweb_config ): - raise Exception( "Required file %s does not exist." % str( hgweb_config ) ) + hgweb_config = trans.app.hgweb_config_manager.hgweb_config def make_web_app(): hgwebapp = hgwebdir( hgweb_config ) return hgwebapp diff -r 3024a86c0d0d21b1a85ff1b91516f34f416bcfcb -r d3ac39a6f8d7a5f95ffabb4ba8f8a846b17ac15a lib/galaxy/webapps/community/controllers/repository.py --- a/lib/galaxy/webapps/community/controllers/repository.py +++ b/lib/galaxy/webapps/community/controllers/repository.py @@ -1,4 +1,4 @@ -import os, logging, tempfile, shutil +import os, logging, tempfile, shutil, ConfigParser from time import strftime from datetime import date, datetime from galaxy import util @@ -11,7 +11,7 @@ from galaxy.model.orm import * # TODO: re-factor shed_util to eliminate the following restricted imports from galaxy.util.shed_util import create_repo_info_dict, generate_clone_url_for_repository_in_tool_shed, generate_message_for_invalid_tools -from galaxy.util.shed_util import get_changectx_for_changeset, get_configured_ui, get_file_from_changeset_revision, get_hgweb_config +from galaxy.util.shed_util import get_changectx_for_changeset, get_configured_ui, get_file_from_changeset_revision from galaxy.util.shed_util import get_repository_file_contents, get_repository_in_tool_shed, get_repository_metadata_by_changeset_revision from galaxy.util.shed_util import handle_sample_files_and_load_tool_from_disk, handle_sample_files_and_load_tool_from_tmp_config from galaxy.util.shed_util import INITIAL_CHANGELOG_HASH, load_tool_from_config, NOT_TOOL_CONFIGS, open_repository_files_folder, remove_dir @@ -530,26 +530,6 @@ repositories_i_own_grid = RepositoriesIOwnGrid() deprecated_repositories_i_own_grid = DeprecatedRepositoriesIOwnGrid() - def __add_hgweb_config_entry( self, trans, repository, repository_path ): - # Add an entry in the hgweb.config file for a new repository. An entry looks something like: - # repos/test/mira_assembler = database/community_files/000/repo_123. - hgweb_config = get_hgweb_config( trans.app ) - if repository_path.startswith( './' ): - repository_path = repository_path.replace( './', '', 1 ) - entry = "repos/%s/%s = %s" % ( repository.user.username, repository.name, repository_path ) - tmp_fd, tmp_fname = tempfile.mkstemp() - if os.path.exists( hgweb_config ): - # Make a backup of the hgweb.config file since we're going to be changing it. - self.__make_hgweb_config_copy( trans, hgweb_config ) - new_hgweb_config = open( tmp_fname, 'wb' ) - for i, line in enumerate( open( hgweb_config ) ): - new_hgweb_config.write( line ) - else: - new_hgweb_config = open( tmp_fname, 'wb' ) - new_hgweb_config.write( '[paths]\n' ) - new_hgweb_config.write( "%s\n" % entry ) - new_hgweb_config.flush() - shutil.move( tmp_fname, os.path.abspath( hgweb_config ) ) @web.expose def browse_categories( self, trans, **kwd ): # The request came from the tool shed. @@ -824,25 +804,14 @@ selected_value=selected_value, refresh_on_change=False, multiple=True ) - def __change_hgweb_config_entry( self, trans, repository, old_repository_name, new_repository_name ): - # Change an entry in the hgweb.config file for a repository. This only happens when - # the owner changes the name of the repository. An entry looks something like: - # repos/test/mira_assembler = database/community_files/000/repo_123. - hgweb_config = get_hgweb_config( trans.app ) - # Make a backup of the hgweb.config file since we're going to be changing it. - self.__make_hgweb_config_copy( trans, hgweb_config ) - repo_dir = repository.repo_path( trans.app ) - old_lhs = "repos/%s/%s" % ( repository.user.username, old_repository_name ) - new_entry = "repos/%s/%s = %s\n" % ( repository.user.username, new_repository_name, repo_dir ) - tmp_fd, tmp_fname = tempfile.mkstemp() - new_hgweb_config = open( tmp_fname, 'wb' ) - for i, line in enumerate( open( hgweb_config ) ): - if line.startswith( old_lhs ): - new_hgweb_config.write( new_entry ) - else: - new_hgweb_config.write( line ) - new_hgweb_config.flush() - shutil.move( tmp_fname, os.path.abspath( hgweb_config ) ) + def __change_repository_name_in_hgrc_file( self, hgrc_file, new_name ): + config = ConfigParser.ConfigParser() + config.read( hgrc_file ) + config.read( hgrc_file ) + config.set( 'web', 'name', new_name ) + new_file = open( hgrc_file, 'wb' ) + config.write( new_file ) + new_file.close() @web.expose def check_for_updates( self, trans, **kwd ): """Handle a request from a local Galaxy instance.""" @@ -1001,8 +970,9 @@ os.makedirs( repository_path ) # Create the local repository repo = hg.repository( get_configured_ui(), repository_path, create=True ) - # Add an entry in the hgweb.config file for the local repository, enabling calls to repository.repo_path( trans.app ) - self.__add_hgweb_config_entry( trans, repository, repository_path ) + # 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 ) # Create a .hg/hgrc file for the local repository self.__create_hgrc_file( trans, repository ) flush_needed = False @@ -1616,13 +1586,6 @@ changeset_revision=changeset_revision, message=message, status='error' ) ) - def __make_hgweb_config_copy( self, trans, hgweb_config ): - # Make a backup of the hgweb.config file - today = date.today() - backup_date = today.strftime( "%Y_%m_%d" ) - hgweb_config_backup_filename = 'hgweb.config_%s_backup' % backup_date - hgweb_config_copy = os.path.join( trans.app.config.hgweb_config_dir, hgweb_config_backup_filename ) - shutil.copy( os.path.abspath( hgweb_config ), os.path.abspath( hgweb_config_copy ) ) def __make_same_length( self, list1, list2 ): # If either list is 1 item, we'll append to it until its length is the same as the other. if len( list1 ) == 1: @@ -1710,7 +1673,14 @@ if message: error = True else: - self.__change_hgweb_config_entry( trans, repository, repository.name, repo_name ) + # Change the entry in the hgweb.config file for the repository. + old_lhs = "repos/%s/%s" % ( repository.user.username, repository.name ) + new_lhs = "repos/%s/%s" % ( repository.user.username, repo_name ) + new_rhs = "%s\n" % repo_dir + trans.app.hgweb_config_manager.change_entry( old_lhs, new_lhs, new_rhs ) + # Change the entry in the repository's hgrc file. + hgrc_file = os.path.join( repo_dir, '.hg', 'hgrc' ) + self.__change_repository_name_in_hgrc_file( hgrc_file, repo_name ) repository.name = repo_name flush_needed = True elif repository.times_downloaded != 0 and repo_name != repository.name: diff -r 3024a86c0d0d21b1a85ff1b91516f34f416bcfcb -r d3ac39a6f8d7a5f95ffabb4ba8f8a846b17ac15a lib/galaxy/webapps/community/model/__init__.py --- a/lib/galaxy/webapps/community/model/__init__.py +++ b/lib/galaxy/webapps/community/model/__init__.py @@ -6,7 +6,6 @@ """ import os.path, os, errno, sys, codecs, operator, logging, tarfile, mimetypes, ConfigParser from galaxy import util -from galaxy.util.shed_util import get_hgweb_config from galaxy.util.bunch import Bunch from galaxy.util.hash_util import * from galaxy.web.form_builder import * @@ -110,12 +109,7 @@ MARKED_FOR_REMOVAL = 'r', MARKED_FOR_ADDITION = 'a', NOT_TRACKED = '?' ) - # Handle to the hgweb.config file on disk. - hgweb_config_file = None - # This repository's entry in the hgweb.config file on disk. - hgweb_path = None - def __init__( self, name=None, description=None, long_description=None, user_id=None, private=False, email_alerts=None, times_downloaded=0, - deprecated=False ): + def __init__( self, name=None, description=None, long_description=None, user_id=None, private=False, email_alerts=None, times_downloaded=0, deprecated=False ): self.name = name or "Unnamed repository" self.description = description self.long_description = long_description @@ -124,27 +118,8 @@ self.email_alerts = email_alerts self.times_downloaded = times_downloaded self.deprecated = deprecated - def get_hgweb_config_file( self, app ): - if self.hgweb_config_file is None: - self.hgweb_config_file = get_hgweb_config( app ) - return self.hgweb_config_file - def get_hgweb_path( self, app ): - # TODO: If possible, handle this using the mercurial api. - if self.hgweb_path is None: - lhs = os.path.join( "repos", self.user.username, self.name ) - config = ConfigParser.ConfigParser() - config.read( self.get_hgweb_config_file( app ) ) - for option in config.options( "paths" ): - if option == lhs: - self.hgweb_path = config.get( "paths", option ) - break - if self.hgweb_path is None: - raise Exception( "Entry for repository %s missing in file %s." % ( lhs, hgweb_config ) ) - return self.hgweb_path def repo_path( self, app ): - # Repository locations on disk are stored in the hgweb.config file located in the directory defined by the config setting hgweb_config_dir. - # An entry looks something like: repos/test/mira_assembler = database/community_files/000/repo_123 - return self.get_hgweb_path( app ) + return app.hgweb_config_manager.get_entry( os.path.join( "repos", self.user.username, self.name ) ) def revision( self, app ): repo = hg.repository( ui.ui(), self.repo_path( app ) ) tip_ctx = repo.changectx( repo.changelog.tip() ) diff -r 3024a86c0d0d21b1a85ff1b91516f34f416bcfcb -r d3ac39a6f8d7a5f95ffabb4ba8f8a846b17ac15a lib/galaxy/webapps/community/model/mapping.py --- a/lib/galaxy/webapps/community/model/mapping.py +++ b/lib/galaxy/webapps/community/model/mapping.py @@ -14,6 +14,7 @@ from galaxy.model.custom_types import * from galaxy.util.bunch import Bunch from galaxy.util.shed_util import ShedCounter +from galaxy.webapps.community.util.hgweb_config import * from galaxy.webapps.community.security import CommunityRBACAgent metadata = MetaData() @@ -318,4 +319,5 @@ # Load local tool shed security policy result.security_agent = CommunityRBACAgent( result ) result.shed_counter = ShedCounter( result ) + result.hgweb_config_manager = HgWebConfigManager() return result diff -r 3024a86c0d0d21b1a85ff1b91516f34f416bcfcb -r d3ac39a6f8d7a5f95ffabb4ba8f8a846b17ac15a lib/galaxy/webapps/community/util/hgweb_config.py --- /dev/null +++ b/lib/galaxy/webapps/community/util/hgweb_config.py @@ -0,0 +1,63 @@ +import sys, os, ConfigParser, logging, shutil +from time import strftime +from datetime import date + +log = logging.getLogger( __name__ ) + +class HgWebConfigManager( object ): + def __init__( self ): + self.hgweb_config_dir = None + self.in_memory_config = None + def add_entry( self, lhs, rhs ): + """Add an entry in the hgweb.config file for a new repository.""" + # Since we're changing the config, make sure the latest is loaded into memory. + self.read_config( force_read=True ) + # An entry looks something like: repos/test/mira_assembler = database/community_files/000/repo_123. + if rhs.startswith( './' ): + rhs = rhs.replace( './', '', 1 ) + self.make_backup() + # Add the new entry into memory. + self.in_memory_config.set( 'paths', lhs, rhs ) + # Persist our in-memory configuration. + self.write_config() + def change_entry( self, old_lhs, new_lhs, new_rhs ): + """Change an entry in the hgweb.config file for a repository - this only happens when the owner changes the name of the repository.""" + self.make_backup() + # Remove the old entry. + self.in_memory_config.remove_option( 'paths', old_lhs ) + # Add the new entry. + self.in_memory_config.set( 'paths', new_lhs, new_rhs ) + # Persist our in-memory configuration. + self.write_config() + def get_entry( self, lhs ): + """Return an entry in the hgweb.config file for a repository""" + self.read_config() + try: + entry = self.in_memory_config.get( 'paths', lhs ) + except ConfigParser.NoOptionError: + raise Exception( "Entry for repository %s missing in file %s." % ( lhs, self.hgweb_config ) ) + return entry + @property + def hgweb_config( self ): + hgweb_config = os.path.join( self.hgweb_config_dir, 'hgweb.config' ) + if not os.path.exists( hgweb_config ): + raise Exception( "Required file %s does not exist - check config setting for hgweb_config_dir." % hgweb_config ) + return os.path.abspath( hgweb_config ) + def make_backup( self ): + # Make a backup of the hgweb.config file. + today = date.today() + backup_date = today.strftime( "%Y_%m_%d" ) + hgweb_config_backup_filename = 'hgweb.config_%s_backup' % backup_date + hgweb_config_copy = os.path.join( self.hgweb_config_dir, hgweb_config_backup_filename ) + shutil.copy( os.path.abspath( self.hgweb_config ), os.path.abspath( hgweb_config_copy ) ) + def read_config( self, force_read=False ): + if force_read or self.in_memory_config is None: + config = ConfigParser.ConfigParser() + config.read( self.hgweb_config ) + self.in_memory_config = config + def write_config( self ): + """Writing the in-memory configuration to the hgweb.config file on disk.""" + config_file = open( self.hgweb_config, 'wb' ) + self.in_memory_config.write( config_file ) + config_file.close + \ No newline at end of file Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.
participants (1)
-
Bitbucket