Skip to content
cschaerfe edited this page Feb 20, 2015 · 2 revisions

You can create a new ballaxy instance by running the following Python script on the computer you would like to install ballaxy on:

#!/usr/bin/python
# -*- coding: latin-1 -*-
"""
SYNOPSIS

    This script creates a ballaxy instance for you.

DESCRIPTION

    This script creates a ballaxy instance for you. You can specify whether or not you want this installation to be created in the current folder or whether or not you would like to use some external or already existing folders. If no existing folders are specified this script attempts to fetch all the necessary data from the ball and galaxy repository respectively. After doing so it attempts to compile ball with the target "ballaxy" in order to create all necessary files. These files are copied to the right destinations within the galaxy folder afterwards.

EXAMPLES

    python galaxy2ballaxy.py - This command creates a folder "ball" and a folder "galaxy" within the current folder and gets all the necessary data from the internet. It compiles ball and copies all files needed in order to get a fully working ballaxy setup.

AUTHOR

    Lukas Brausch <[email protected]>

LICENSE

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

VERSION

    0.2
"""

import sys, os, traceback, optparse
import time, re, errno, shutil
from lxml import etree

def copyDataFile(ballFolder,galaxyFolder):
    originDataPy = ballFolder + "/data/galaxy/data.py"
    destinationDataPy = galaxyFolder + "/galaxy-dist/lib/galaxy/datatypes/data.py"
    shutil.copyfile(originDataPy,destinationDataPy)
    print "copied '" + originDataPy + "' to '" + destinationDataPy + "'"	

def keepToolsAndCopyXMLSection(ballFolder,galaxyFolder):
	toolConfSample = galaxyFolder+"/galaxy-dist/" + "tool_conf.xml.sample"
	toolConf = galaxyFolder+"/galaxy-dist/" + "tool_conf.xml"

	toolConfSampleTree = etree.parse(toolConfSample)
	toolConfTree = etree.parse(toolConf)
        toolConfTreeToolboxTag = toolConfTree.getroot()
	toolConfSampleTreeToolboxTag = toolConfSampleTree.getroot()
	for section in toolConfSampleTreeToolboxTag:
	    toolConfTreeToolboxTag.append(section)
	outFile = open(toolConf, 'w')
	toolConfTree.write(outFile, xml_declaration=True, pretty_print=True) 

def addSniffersToOutputTree(inputTree,sampleTree,outputTree):
    inputSniffersTag = inputTree.find('sniffers')
    outputSniffersTag = outputTree.find('sniffers')
    sampleSniffersTag = sampleTree.find('sniffers')
    for inputNode in inputSniffersTag:
	outputSniffersTag.append(inputNode)
    for sampleNode in sampleSniffersTag:
	outputSniffersTag.append(sampleNode)

def addDatatypesToOutputTree(inputTree,sampleTree,outputTree):
    inputRegistrationTag = inputTree.find('registration')
    sampleRegistrationTag = sampleTree.find('registration')
    outputRegistrationTag = outputTree.find('registration')
    for inputNode in inputRegistrationTag:
	outputRegistrationTag.append(inputNode)
    for sampleNode in sampleRegistrationTag:
	outputRegistrationTag.append(sampleNode)

def getPreparedTree():
    datatypesTag = etree.Element('datatypes')
    registrationTag = etree.Element('registration')
    sniffersTag = etree.Element('sniffers')
    datatypesTag.append(registrationTag)
    datatypesTag.append(sniffersTag)

    tree = etree.ElementTree(datatypesTag)
    return tree

def copyDatatypeFiles(ballFolder,galaxyFolder,keepDatatypes):
    if keepDatatypes:
	destinationDatatypesConf = galaxyFolder + "/galaxy-dist/datatypes_conf.xml"
	destinationDatatypesSampleConf = galaxyFolder + "/galaxy-dist/datatypes_conf.xml.sample"
	originDatatypesConf = ballFolder + "/data/galaxy/datatypes_conf.xml"
	createdTree = getPreparedTree()
	sampleConfTree = etree.parse(destinationDatatypesSampleConf)
	originConfTree = etree.parse(originDatatypesConf)
	addDatatypesToOutputTree(originConfTree,sampleConfTree,createdTree)
	addSniffersToOutputTree(originConfTree,sampleConfTree,createdTree)
	outFile = open(destinationDatatypesConf, 'w')
	createdTree.write(outFile, xml_declaration=True, pretty_print=True) 
    else:
        destinationDatatypesConf = galaxyFolder + "/galaxy-dist/datatypes_conf.xml"
        originDatatypesConf = ballFolder + "/data/galaxy/datatypes_conf.xml"
	shutil.copyfile(originDatatypesConf,destinationDatatypesConf)
	print "copied '" + originDatatypesConf + "' to '" + destinationDatatypesConf + "'"

    originXmlPy = ballFolder + "/data/galaxy/xml.py"
    destinationXmlPy = galaxyFolder + "/galaxy-dist/lib/galaxy/datatypes/xml.py"
    shutil.copyfile(originXmlPy,destinationXmlPy)
    print "copied '" + originXmlPy + "' to '" + destinationXmlPy + "'"
	
def copyXMLSection(ballFolder,galaxyFolder,keepTools):
    os.chdir(ballFolder)
    os.chdir("build/ballaxy/default")
    with open ("tool_conf.xml.section", "r") as ballToolConfFile:
	data = ballToolConfFile.readlines()
    os.chdir(galaxyFolder)
    os.chdir("galaxy-dist")
    open('tool_conf.xml', 'w').close()
    with open('tool_conf.xml', 'a') as galaxyToolConfFile:
	galaxyToolConfFile.write('<?xml version="1.0"?>\n')
	galaxyToolConfFile.write('<toolbox>\n')
	for line in data:
	    galaxyToolConfFile.write(line)
	galaxyToolConfFile.write('</toolbox>\n')
    if keepTools:
	keepToolsAndCopyXMLSection(ballFolder,galaxyFolder)
	
def createSymLink(ballFolder,galaxyFolder):
    os.chdir(galaxyFolder)
    os.chdir("galaxy-dist/tools")
    pathToConfig = ballFolder + "/build/ballaxy/default/config/"
    os.system("ln -s " + pathToConfig + " BALL")

def compileBall(ballFolder):
    createFolder(ballFolder+"/build")
    os.chdir(ballFolder+"/build")
    os.system("cmake .. -DBALL_BUILD_BALLAXY=true")
    os.system("make -j2 ballaxy")
	
def handleGalaxyFolder(galaxyFolder):
    if not (os.path.isdir(galaxyFolder)):
	createFolder(galaxyFolder)
    if (os.listdir(galaxyFolder) == []):
	print 'Now we need to get the galaxy server. Please stay tuned and hold your breath for a short while...'
	os.chdir(galaxyFolder)
	os.system("hg clone https://bitbucket.org/galaxy/galaxy-dist")
	os.chdir(galaxyFolder + "/galaxy-dist")
	os.system("hg update stable")
	return galaxyFolder
    else:
	try:
	   os.chdir(galaxyFolder)
	   os.chdir("galaxy-dist/tools") #Try to switch to the galaxy-dist/tools folder to check whether or not we are in the galaxy folder
	   return galaxyFolder
	except OSError as exception:
	   print "Sorry, the given folder doesn't seem to be the galaxy repository. Please specify another folder. Aborting the script..."
	   sys.exit()

def handleBallFolder(ballFolder):
    if not (os.path.isdir(ballFolder)):
	createFolder(ballFolder)
    if (os.listdir(ballFolder) == []):
	print 'In order to compile BALL, we need to get the source code first. Please stay tuned and hold your breath for a short while...'
	os.chdir(ballFolder)
	os.system("git clone https://bitbucket.org/ball/ball")
	return ballFolder + "/ball"
    else:
	try:
	   os.chdir(ballFolder)
	   os.chdir("source/APPLICATIONS") #Try to switch to the source/APPLICATIONS folder to check whether or not we are in the ball folder
	   return ballFolder
	except OSError as exception:
	   print "Sorry, the given folder doesn't seem to be the ball repository. Please specify another folder. Aborting the script..."
	   sys.exit()

def createFolder(folder):
    try:
	os.makedirs(folder)
	print "The folder \"" + folder + "\" didn't exist yet. Creating it for you."
    except OSError as exception:
	if exception.errno != errno.EEXIST:
	    print "Sorry, couldn't create the folder \"" + folder +"\". Please check if you have the permission to do so. Aborting the script..."
	    sys.exit()

def linePrepender(filename,line):
    with open(filename,'r+') as f:
        content = f.read()
        f.seek(0,0)
        f.write(line.rstrip('\r\n') + '\n' + content)

def writeExportLinesToRunSh(ballFolder,filename):
    linePrepender(filename,"export PYTHONPATH=" + ballFolder + "/build/lib/")
    linePrepender(filename,"export LD_LIBRARY_PATH=" + ballFolder + "/build/lib/")
    linePrepender(filename,"export BALL_DATA_PATH=" + ballFolder + "/data/")
    linePrepender(filename,"export PATH=$PATH:" + ballFolder + "/build/bin/")
    linePrepender(filename,"export PATH=$PATH:" + ballFolder + "/build/bin/TOOLS/")

def main (ballFolder,galaxyFolder,keepDatatypes,keepTools):
    global options, args
    if (galaxyFolder == None or galaxyFolder == ""):
	galaxyFolder = os.getcwd() + "/galaxy"
    if (ballFolder == None or ballFolder == ""):
	ballFolder = os.getcwd() + "/ball"
    ballFolder = handleBallFolder(ballFolder)
    compileBall(ballFolder)
    galaxyFolder = handleGalaxyFolder(galaxyFolder)
    createSymLink(ballFolder,galaxyFolder)
    copyXMLSection(ballFolder,galaxyFolder,keepTools)
    copyDatatypeFiles(ballFolder,galaxyFolder,keepDatatypes)
    copyDataFile(ballFolder,galaxyFolder)
    runsh = galaxyFolder + "/galaxy-dist/" + "run.sh"
    writeExportLinesToRunSh(ballFolder,runsh)
    print "Congratulations, ballaxy should now be ready to use. In order to start the server please execute the command './run.sh' in the folder '" + galaxyFolder + "/galax-dist'."
    
if __name__ == '__main__':
    try:
        start_time = time.time()
        parser = optparse.OptionParser(formatter=optparse.TitledHelpFormatter(), usage=globals()['__doc__'], version='0.1.0')
    	parser.add_option ('-v', '--verbose', action='store_true', default=False, help='verbose output')
	parser.add_option ('-b', '--ballFolder', help='specifies the folder in which the ball source code resides')
	parser.add_option ('-g', '--galaxyFolder', help='specifies the folder in which the galaxy server resides')
	parser.add_option ('-d', '--keepDatatypes', action='store_true', default=False, help='specifies whether or not the galaxy datatypes should be kept')
        parser.add_option ('-t', '--keepTools', action='store_true', default=False, help='specifies whether or not the galaxy tools should be kept')
        (options, args) = parser.parse_args()
        #if len(args) < 1:
        #    parser.error ('missing argument')
        if options.verbose: print time.asctime()
        main(options.ballFolder,options.galaxyFolder,options.keepDatatypes,options.keepTools)
        if options.verbose: print time.asctime()
        if options.verbose: print 'TOTAL TIME IN MINUTES:',
        if options.verbose: print (time.time() - start_time) / 60.0
        sys.exit(0)
    except KeyboardInterrupt, e: # Ctrl-C
        raise e
    except SystemExit, e: # sys.exit()
        raise e
    except Exception, e:
        print 'ERROR, UNEXPECTED EXCEPTION'
        print str(e)
        traceback.print_exc()
        os._exit(1)
Clone this wiki locally