#!/usr/bin/env python3 import os, os.path, sys, shutil, re, getpass, urllib.request, urllib.parse, urllib.error, subprocess import birchhome, customdoc, htmldoc, newuser, setplatform, update_local ''' birch_install.py - Performs the tasks necessary for a complete installation of BIRCH @param installDir the target location to install BIRCH @param logger the output log/console to use to display progress information @param adminEmail the administrator's email address to use for the installation @param install whether to install or update birch (true = install) @param minibirch whether to install miniBIRCH @modified: January 20, 2020 @author: Brian Fristensky @contact: brian.fristensky@umanitoba.ca ''' def run_pyinstall (PLATFORM, installDir, adminEmail, install, minibirch): username = getpass.getuser() admindir = os.path.join(installDir, "admin" ) installBIRCH = os.path.join(installDir, "install-scripts" ) local = os.path.join(installDir, "local" ) phtml = os.path.join(installDir, "public_html" ) scriptdir = os.path.join(installDir, "script" ) htmldirParam = os.path.join(installBIRCH, "htmldir.param" ) localgeneric = os.path.join(installDir, "local-generic" ) oldstrParam = os.path.join(installBIRCH, "oldstr.param" ) ladmin = os.path.join(local, "admin" ) pfile = os.path.join(ladmin, "BIRCH.properties" ) paramfile = os.path.join(ladmin, "newstr.param" ) installDirURL = 'file://' + urllib.request.pathname2url(os.path.abspath(installDir)) phtmlDirURL = 'file://' + urllib.request.pathname2url(os.path.abspath(phtml)) if install: # New install only: create a new local directory for BIRCH print ("Moving local-generic to local") shutil.move(localgeneric, local) #---------------------- Steps for both new install and update ---------------------- # configure Birchhome print ('') print ('') print ('') print ("********************Birchhome********************") print ("Running birchhome") # need to update this once default install is using BIRCHDEV # birchhome.main(install_dir,homepath); birchhome.birchhome(installDir) # need to run setplatform print ('') print ("********************Setplatform********************") print("Setting birch platform to " + PLATFORM) print("Using install dir: " + installDir) setplatform.setplatform(installDir) os.chdir(os.path.join(installDir, "install-scripts")) #---------------------- Steps for New Installation only ---------------------- if install: print ('') print ('') print ("---------------------- NEW BIRCH INSTALLATION ----------------------") # write a new BIRCH.properties file print ("Writing BIRCH.properties") props = open (pfile, "w+") props.write("BirchProps.homedir=" + installDir + '\n') props.write("BirchProps.adminUserid=" + username + '\n') props.write("BirchProps.birchURL=" + phtmlDirURL + '\n') props.write("BirchProps.adminEmail=" + adminEmail + '\n') props.write("BirchProps.platform=" + PLATFORM + '\n') # BirchProps.BirchMasterCopy props.write("BirchProps.birchHomeURL=" + installDirURL + '\n') props.write("BirchProps.minibirch=" + str(minibirch) + '\n') props.close() if os.path.exists(pfile): print ("Birch properties file written successfully") else: print ("Error, properties file not written!") #Call BLHelper.py to set default values for BioLegato helper apps. # We BLHelper.py using subprocess.Popen, mainly because I don't know # how to call an imported script that doesn't take a fixed number of arguments. # There probably is a way, but I haven't found it online. print ('') print ("******************** BLHelper.py ********************") print ("Running BLHelper.py") # We need to flush the standard output at this point. If we don't, the # messages from BLHelper.py will appear BEFORE any other install message. sys.stdout.flush() scriptpath = os.path.join(installDir, 'install-scripts', 'BLHelper.py') p = subprocess.Popen(["python3", scriptpath, "--install", "--platform", PLATFORM, "--birchdir", installDir]) p.wait() # Call BIRCHSettings.py to set default values for BioLegato helper apps. # We call BIRCHSettings.py using subprocess.Popen, mainly because I don't know # how to call an imported script that doesn't take a fixed number of arguments. # There probably is a way, but I haven't found it online. print ('') print ("******************** BIRCHSettings.py ********************") print ("Running BIRCHSettings.py") # We need to flush the standard output at this point. If we don't, the # messages from BIRCHSettings.py will appear BEFORE any other install message. sys.stdout.flush() scriptpath = os.path.join(installDir, 'install-scripts', 'BIRCHSettings.py') p = subprocess.Popen(["python3", scriptpath, "--install", "--birchdir", installDir]) p.wait() #Call blastdbkit.py to set BLASTDB environment variable, and to # Set up menus in birchadmin for installing, updating and deleting # local copies of BLAST databases. Also creates menus in bldna and blprotein. # for searching these databases print ('') print ("******************** blastdbkit.py ********************") print ("Running blastdbkit.py") # We need to flush the standard output at this point. If we don't, the # messages from BIRCHSettings.py will appear BEFORE any other install message. sys.stdout.flush() scriptpath = os.path.join(installDir, 'install-scripts', 'blastdbkit.py') blastdbDir = os.path.join(installDir, 'GenBank') p = subprocess.Popen(["python3", scriptpath, "--configure", "--birchdir", installDir, "--blastdb", blastdbDir]) p.wait() #---------------------- Steps for Update only ---------------------- else: # Update an existing installation print ('') print ('') print ("---------------------- UPDATING BIRCH ----------------------") print ("Parsing BIRCH properties file") # These variables will be needed for running customdoc.py props = open (pfile, "r") for line in props: if not (line.startswith('#')) : if '=' in line: fields = line.split('=') if fields[0].lower() == 'birchprops.adminemail': adminEmail = str(fields[1]).rstrip("\n\r") print("Setting the BIRCH administrator's email to: " + adminEmail) elif fields[0].lower() == 'birchprops.birchurl': installDirURL = str(fields[1]).rstrip("\n\r") print("Setting the URL for the local BIRCH web site to: " + installDirURL) elif fields[0].lower() == 'birchprops.birchhomeurl': phtmlDirURL = str(fields[1]).rstrip("\n\r") print("Setting the URL for the local BIRCH documentation to: " + phtmlDirURL) props.close() # Turn off BIRCH access import nobirch nobirch.nobirch(installDir) # copy new files from local-generic to existing local directory print ('') print ("******************** update_local.py ********************") print ("Running update_local.py") update_local.update_local() #Call BLHelper.py to set default values for BioLegato helper apps. # We BLHelper.py using subprocess.Popen, mainly because I don't know # how to call an imported script that doesn't take a fixed number of arguments. # There probably is a way, but I haven't found it online. print ('') print ("******************** BLHelper.py ********************") print ("Running BLHelper.py") # We need to flush the standard output at this point. If we don't, the # messages from BLHelper.py will appear BEFORE any other install message. sys.stdout.flush() scriptpath = os.path.join(installDir, 'install-scripts', 'BLHelper.py') p = subprocess.Popen(["python3", scriptpath, "--update", "--platform", PLATFORM, "--birchdir", installDir]) p.wait() #Call BIRCHSettings.py to set default values for BioLegato helper apps. # We BIRCHSettings.py using subprocess.Popen, mainly because I don't know # how to call an imported script that doesn't take a fixed number of arguments. # There probably is a way, but I haven't found it online. print ('') print ("******************** BIRCHSettings.py ********************") print ("Running BIRCHSettings.py") # We need to flush the standard output at this point. If we don't, the # messages from BIRCHSettings.py will appear BEFORE any other install message. sys.stdout.flush() scriptpath = os.path.join(installDir, 'install-scripts', 'BIRCHSettings.py') p = subprocess.Popen(["python3", scriptpath, "--update", "--birchdir", installDir]) p.wait() # Call blastdbkit.py to set BLASTDB environment variable, and to # Set up menus in birchadmin for installing, updating and deleting # local copies of BLAST databases. Also creates menus in bldna and blprotein. # for searching these databases print ('') print ("******************** blastdbkit.py ********************") print ("Running blastdbkit.py") # We need to flush the standard output at this point. If we don't, the # messages from BIRCHSettings.py will appear BEFORE any other install message. sys.stdout.flush() scriptpath = os.path.join(installDir, 'install-scripts', 'blastdbkit.py') p = subprocess.Popen(["python3", scriptpath, "--configure", "--birchdir", installDir]) p.wait() props = None #---------------------- Steps for both new install and update ---------------------- print ('') print ("********************Customdoc********************") print ("Making new paramfile for customdoc") pwriter = open(paramfile, "w+") pwriter.write("~" + '\n') pwriter.write(phtmlDirURL + '\n') pwriter.write(installDirURL + '\n') pwriter.write(adminEmail + '\n') pwriter.write(installDir + '\n') pwriter.write(username + '\n') pwriter.close() print ("Running customdoc.py") customdoc.customdoc(oldstrParam, paramfile, htmldirParam) print ('') print ("********************Htmldoc********************") print ("Running htmldoc.py") # htmldoc.htmldoc(installDir, PLATFORM) htmldoc.main() # RUN THE NEWUSER SCRIPT print ('') print ("********************Newuser********************") print ("Running newuser") newuser.newuser(installDir, PLATFORM) print ("Running newuser") # Get rid of the legacy install-birch directory, if it exists print ('') filename = os.path.join(installDir, "install-birch") if (os.path.exists(filename)) : print("Deleting " + filename) shutil.rmtree(filename) print ('') print ('') print ("********************** birch_install DONE! *******************************") if __name__=="__main__": if len(sys.argv) > 4: PLATFORM = sys.argv[1] installDir = sys.argv[2] adminEmail = sys.argv[3] install = (sys.argv[4].upper() == "Y") minibirch = (sys.argv[5].upper() == "Y") if installDir.find("BIRCHDEV") > -1: print ('>>> birch_install.py cannot be run in BIRCHDEV') print ('>>> Doing so would clobber the master copy of BIRCH') sys.exit(1) else: print ('') print ('===========================================================') print ('| |') print ('| Running birch_install.py |') print ('| |') print ('===========================================================') run_pyinstall (PLATFORM, installDir, adminEmail, install, minibirch) else: print ("ERROR!!! INCORRECT NUMBER OF COMMAND LINE ARGUMENTS SPECIFIED!") print ("Usage: birch_install.py ") sys.exit(1)