class Jinn(FileSystemHelper): # Header for messages header = """ .---. | | '---'.--. _..._ _..._ .---.|__| .' '. .' '. | |.--.. .-. .. .-. . | || || ' ' || ' ' | | || || | | || | | | | || || | | || | | | | || || | | || | | | | ||__|| | | || | | | __.' ' | | | || | | | | ' | | | || | | | |____.' '--' '--''--' '--' A Java installer""" def __init__(self): self.new_manifest = None self.manifest = None self.args = "" # Setup feedback mechanism global feedback if (options.interface == FeedbackMechanisms.CMD): g.feedback = ConsoleFeedback() elif (options.interface == FeedbackMechanisms.UI): g.feedback = UIFeedback() else: # Not specified, need something to stop errors, so us this g.feedback = FeedbackBase() # Setup min log level g.feedback.minLogLevel = LogLevels.getLevelFromString( options.min_log_level) self.os = self.getOperatingSystem() self.arch = self.getArchitecture() g.feedback.log( LogLevels.INFO, "Started up. OS: %s; Architecture: %s" % (OperatingSystem().getOperatingSystem( self.os), Architecture().getArchitecture(self.arch))) """ Gets the current OS """ def getOperatingSystem(self): p = platform.system() if p == "Windows": return OperatingSystem.WIN elif p == "Darwin": return OperatingSystem.OSX elif p == "Linux": return OperatingSystem.LIN else: g.feedback.log(LogLevels.ERROR, "Unable to work with operating system %s" % p) raise OperatingSystemNotFoundException(p) """ Gets the current architecture """ def getArchitecture(self): if self.os is OperatingSystem.WIN: g.feedback.log( LogLevels.DEBUG, "Getting architecture, we are windows, so asking the registry") return self.getArchitectureWindows() else: g.feedback.log(LogLevels.DEBUG, "Working out if we are running 32 or 64 bit") if (sys.maxsize > 2**32): g.feedback.log(LogLevels.DEBUG, "Decided 64 bit") return Architecture.x64 else: g.feedback.log(LogLevels.DEBUG, "Decided 32 bit") return Architecture.x32 """ Windows special case for getting architecture """ def getArchitectureWindows(self): from _winreg import * softwarekey = OpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE") microsoftkey = OpenKey(softwarekey, "Microsoft") windowskey = OpenKey(microsoftkey, "Windows NT") versionkey = OpenKey(windowskey, "CurrentVersion") value = QueryValueEx(versionkey, "BuildLabEx")[0] CloseKey(versionkey) CloseKey(windowskey) CloseKey(microsoftkey) CloseKey(softwarekey) if "amd64" in value: g.feedback.log(LogLevels.DEBUG, "From value %s, decided we are 64 bit" % value) return Architecture.x64 else: g.feedback.log(LogLevels.DEBUG, "From value %s, decided we are 32 bit" % value) return Architecture.x32 """ Loads the manifest file """ def loadManifest(self): g.feedback.log(LogLevels.INFO, "Loading new manifest from %s" % options.manifest) self.new_manifest = Manifest(self.os, self.arch, options.manifest, options.manifest_is_url) if self.isInstalled(): manifest_file = ".jinn" + self.sep() + "current_manifest.json" g.feedback.log(LogLevels.INFO, "Loading manifest from %s" % manifest_file) self.manifest = Manifest(self.os, self.arch, manifest_file, False, True) else: g.feedback.log( LogLevels.INFO, "Loading manifest from new manifest, as not installed") self.manifest = self.new_manifest """ A helper which sets up the system before a run """ def setupSystem(self): g.feedback.log(LogLevels.INFO, "Setting up the system") # Make sure we are installed if not self.isInstalled(): g.feedback.log(LogLevels.INFO, "We aren't installed, so installing") status = self.doInstall() if status != 0: g.feedback.log(LogLevels.ERROR, "Tried installing but failed horribly") g.feedback.userMessage( "Installation failed (1) - please contact distributor") return status g.feedback.log(LogLevels.INFO, "Installation succeeded") else: self.loadManifest() return self.doUpdate() """ Runs the default action in the jinn """ def runDefaultAction(self): g.feedback.log(LogLevels.DEBUG, "Running default action") self.setupSystem() g.feedback.log(LogLevels.DEBUG, "Default action execution commencing") try: self.manifest.runDefaultAction(self.args) g.feedback.log(LogLevels.DEBUG, "Run default action executed successfully") return 0 except Exception as e: g.feedback.log(LogLevels.ERROR, "Running default action threw exception %s" % e) return 1 """ Runs a specific action within the jinn """ def runAction(self, action): g.feedback.log(LogLevels.INFO, "Running %s action" % action) self.setupSystem() g.feedback.log(LogLevels.DEBUG, "Run action %s" % action) try: self.manifest.runAction(action, self.args) g.feedback.log(LogLevels.INFO, "Running action %s successfully completed" % action) return 0 except Exception as e: g.feedback.log( LogLevels.ERROR, "Running action %s threw exception %s" % (action, e)) return 1 """ Are we in dev mode? """ def isDevMode(self): isDev = options.version is "DEV" g.feedback.log(LogLevels.WARN, "Dev mode? %s" % str(isDev)) return isDev """ Checks the manifests for updates """ def doUpdate(self): g.feedback.log(LogLevels.DEBUG, "Starting update procedure") # No update if the version number is the same if self.manifest.jinn.version == self.new_manifest.jinn.version: g.feedback.log( LogLevels.DEBUG, "New and current manifest versions are %s and %s, so skipping update as they are identical" % (self.manifest.jinn.version, self.new_manifest.jinn.version)) return True g.feedback.log(LogLevels.DEBUG, "Setting installation status across manifests") # Initially, set the resources that are installed on the new manifest already if not self.new_manifest.setInstallStatus(self.manifest.resources): g.feedback.log(LogLevels.ERROR, "Failed to set install status") return False g.feedback.log(LogLevels.INFO, "Installing new resources") # First, install resources that are new if not self.new_manifest.installNewResources(self.manifest.resources): g.feedback.log(LogLevels.ERROR, "Failed to install new resources") return False g.feedback.log(LogLevels.INFO, "Uninstalling removed resources") # Second, uninstall resources that are gone if not self.new_manifest.uninstallRemovedResources( self.manifest.resources): g.feedback.log(LogLevels.ERROR, "Removing resources failed") return False g.feedback.log(LogLevels.INFO, "Updating changed resources") # Third, update resources that are new version if not self.new_manifest.updateResources(self.manifest.resources): g.feedback.log(LogLevels.ERROR, "Updating changed resources failed") return False g.feedback.log(LogLevels.DEBUG, "Saving manifest") # Finally, transition the manifest over to the new one self.manifest = self.new_manifest if not self.manifest.save(): g.feedback.log(LogLevels.ERROR, "Unable to save updated manifest") return False # Done! g.feedback.log(LogLevels.DEBUG, "Update complete") return True """ Copy this executable to the target directory, then run it """ def doCopy(self): g.feedback.log( LogLevels.DEBUG, "We are not in the correct directory, so installing to the correct location" ) if self.os is OperatingSystem.OSX: g.feedback.log(LogLevels.DEBUG, "Copying in OS X mode") targetDir = self.getInstallTargetDirectory() copyTargetDir = targetDir.rsplit("/", 2)[0] currentDir = self.getCurrentDirectory() + self.sep( ) + ".." + self.sep() + ".." executable = targetDir + self.sep() + self.getExecutableName() g.feedback.log(LogLevels.DEBUG, "Target executable: %s" % executable) if not self.exists(executable): g.feedback.log(LogLevels.DEBUG, "Target executable does not exist, copying") if not self.makeDirectory(copyTargetDir): return False if not self.copyDir(currentDir, copyTargetDir): return False else: g.feedback.log(LogLevels.DEBUG, "Target executable exists, so running it") cmd = executable + " -install" g.feedback.log(LogLevels.DEBUG, "Executing command: %s" % cmd) res = os.system(cmd) if res < 1: g.feedback.log(LogLevels.DEBUG, "Executed command successfully") return 0 else: g.feedback.log( LogLevels.ERROR, "Executing command %s failed with code %s" % (cmd, str(res))) return 1 else: g.feedback.log(LogLevels.DEBUG, "Copying in Windows / Linux mode") targetFile = self.getInstallTargetFile() g.feedback.log(LogLevels.DEBUG, "Target file is %s" % targetFile) d = self.getInstallTargetDirectory() g.feedback.log(LogLevels.DEBUG, "Target directory is %s" % d) if not self.exists(targetFile): # Make the jinn install directory if not self.makeDirectory(d): g.feedback.log( LogLevels.ERROR, "Unable to make directory %s to install to" % d) return 1 # Copy this binary into it frm = self.getCurrentFile() to = targetFile g.feedback.log(LogLevels.DEBUG, "Copying from %s to %s" % (frm, to)) if not self.copyFile(frm, to): g.feedback.log(LogLevels.ERROR, "Unable to copy %s to %s" % (frm, to)) return 1 # Change into that directory g.feedback.log(LogLevels.DEBUG, "Changing to %s" % d) if not self.changeDirectory(d): g.feedback.log( LogLevels.ERROR, "Unable to change to the InstallTargetDirectory %s" % d) return 1 # Run the new executable g.feedback.log(LogLevels.DEBUG, "Code copied to %s, executing" % targetFile) cmd = self.getExecutableName() + " -install" if self.os == OperatingSystem.LIN or self.os == OperatingSystem.OSX: cmd = "./" + cmd g.feedback.log(LogLevels.DEBUG, "Run command: %s" % cmd) os.system(cmd) return 0 """ Runs an installation of this jinn """ def doInstall(self): g.feedback.log(LogLevels.INFO, "Beginning installation") # We need the manifest first of all self.loadManifest() # Hard code here to not happen for dev correctDir = self.isCorrectDirectory() g.feedback.log(LogLevels.DEBUG, "Are we in correct directory? %s" % str(correctDir)) if not correctDir and not self.isDevMode(): return self.doCopy() # Make sure we are in the right directory installDir = self.getInstallTargetDirectory() g.feedback.log(LogLevels.DEBUG, "Target install dir is %s" % installDir) if not self.changeDirectory(installDir) and not self.isDevMode(): g.feedback.log( LogLevels.ERROR, "Unable to change to where we thought we were installed, %s" % installDir) return 1 if self.isInstalled(): g.feedback.log(LogLevels.ERROR, "This jinn is already installed") g.feedback.userMessage( "Installation failed (3) - please contact distributor") return 1 g.feedback.log(LogLevels.DEBUG, "Installing") if not self.makeDirectory(".jinn"): g.feedback.log(LogLevels.ERROR, "Unable to make .jinn directory") return 1 if not self.manifest.save(): g.feedback.log(LogLevels.ERROR, "Unable to save the manifest") return 1 try: if self.manifest.installResources(): g.feedback.log(LogLevels.DEBUG, "Install resources succeeded") return 0 else: g.feedback.log(LogLevels.ERROR, "Install resources failed") return 1 except Exception as e: g.feedback.log(LogLevels.ERROR, "Unable to install resources: %s" % e) return 1 """ Runs uninstallation """ def doUninstall(self): g.feedback.log(LogLevels.INFO, "Doing uninstallation") if not self.isInstalled(): g.feedback.log( LogLevels.ERROR, "This jinn is not installed, so cannot be uninstalled") g.feedback.userMessage( "Uninstallation failed (4) - please contact distributor") return 1 g.feedback.log(LogLevels.DEBUG, "Uninstalling") self.loadManifest() try: if self.manifest.uninstallResources(): if self.delete(".jinn"): g.feedback.userMessage( "Uninstallation finished. To completely erase this application, please delete the directory %s" % self.getInstallTargetDirectory()) return 0 else: g.feedback.log( LogLevels.ERROR, "Failed to delete .jinn directory, will think its still installed" ) return 1 else: g.feedback.log(LogLevels.ERROR, "Uninstallation failed") return 1 except Exception as e: g.feedback.log(LogLevels.ERROR, "Unable to uninstall: %s" % e) return 1 """ Returns the install target directory """ def getInstallTargetDirectory(self): if self.isDevMode(): return self.getCurrentDirectory() elif self.os is OperatingSystem.OSX: return self.getHomeDirectory() + self.sep( ) + "Applications" + self.sep( ) + self.manifest.jinn.name + ".app" + self.sep( ) + "Contents" + self.sep() + "MacOS" else: return self.getHomeDirectory() + self.getDirectorySeparator( ) + self.manifest.jinn.name """ Get the name of the executable """ def getExecutableName(self): if self.os == OperatingSystem.WIN: return self.manifest.jinn.name + ".jinn.exe" elif self.os == OperatingSystem.LIN: return self.manifest.jinn.name + ".jinn" elif self.os == OperatingSystem.OSX: return "jinn" return None """ Get the file we wish to install to """ def getInstallTargetFile(self): return self.getInstallTargetDirectory() + self.getDirectorySeparator( ) + self.getExecutableName() """ Check whether or not we are running from the right place """ def isCorrectDirectory(self): currentdir = self.getCurrentDirectory() targetdir = self.getInstallTargetDirectory() g.feedback.log(LogLevels.DEBUG, "Current directory: %s" % currentdir) g.feedback.log(LogLevels.DEBUG, "Target dir: %s" % targetdir) return targetdir == currentdir """ Take the sys args and turn them into a string stored on the object for later use. Offset is how many to skip off the front. Automatically skips the first one, the current script """ def processArgs(self, offset=0): args = copy.copy(sys.argv) args.pop(0) i = 0 while i < offset: args.pop(0) i += 1 self.args = " ".join(map(str, args)) g.feedback.log(LogLevels.DEBUG, "System args: %s" % self.args) """ Check whether or not this jinn is currently installed """ def isInstalled(self): return self.directoryExists(".jinn") """ Output the version information """ def doVersion(self): g.feedback.userMessage(""" %s Version: %s """ % (self.header, options.version)) return 0 """ Output the help content """ def doHelp(self): g.feedback.userMessage(""" %s Created by import.io Options: ./jinn Run the jinn with the default action ./jinn -install Run the jinn installation ./jinn -uninstall Uninstall the jinn ./jinn -help Display this helpful help dialog ./jinn -action (actionname) Run the jinn action specified by (actionname) ./jinn -version Print the version string """ % self.header) return 0 """ Runs the jinn feature we need to perform """ def do(self): # Change to the current run directory self.changeDirectory(self.getPathFromFilePath(sys.argv[0])) # Analyse the sys args to figure out what to do if len(sys.argv) < 2: # No extra args, if we are installed we want to run the default action. # Otherwise this is the first run from download, so do install if self.isInstalled(): return self.runDefaultAction() else: return self.doInstall() elif sys.argv[1] == "-install": return self.doInstall() elif sys.argv[1] == "-uninstall": return self.doUninstall() elif sys.argv[1] == "-help": return self.doHelp() elif sys.argv[1] == "-version": return self.doVersion() elif sys.argv[1] == "-action": if len(sys.argv) < 3: g.feedback.userMessage( "For -action, you must specify an action - try -help") return 1 self.processArgs(2) return self.runAction(sys.argv[2]) else: # There are some args, we don't recognise the first, so must want to run default action with some args self.processArgs() return self.runDefaultAction()
class Jinn(FileSystemHelper): # Header for messages header = """ .---. | | '---'.--. _..._ _..._ .---.|__| .' '. .' '. | |.--.. .-. .. .-. . | || || ' ' || ' ' | | || || | | || | | | | || || | | || | | | | || || | | || | | | | ||__|| | | || | | | __.' ' | | | || | | | | ' | | | || | | | |____.' '--' '--''--' '--' A Java installer""" def __init__(self): self.new_manifest = None self.manifest = None self.args = "" # Setup feedback mechanism global feedback if (options.interface == FeedbackMechanisms.CMD): g.feedback = ConsoleFeedback() elif (options.interface == FeedbackMechanisms.UI): g.feedback = UIFeedback() else: # Not specified, need something to stop errors, so us this g.feedback = FeedbackBase() # Setup min log level g.feedback.minLogLevel = LogLevels.getLevelFromString(options.min_log_level) self.os = self.getOperatingSystem() self.arch = self.getArchitecture() g.feedback.log(LogLevels.INFO, "Started up. OS: %s; Architecture: %s" % (OperatingSystem().getOperatingSystem(self.os), Architecture().getArchitecture(self.arch))) """ Gets the current OS """ def getOperatingSystem(self): p = platform.system() if p == "Windows": return OperatingSystem.WIN elif p == "Darwin": return OperatingSystem.OSX elif p == "Linux": return OperatingSystem.LIN else: g.feedback.log(LogLevels.ERROR, "Unable to work with operating system %s" % p) raise OperatingSystemNotFoundException(p) """ Gets the current architecture """ def getArchitecture(self): if self.os is OperatingSystem.WIN: g.feedback.log(LogLevels.DEBUG, "Getting architecture, we are windows, so asking the registry") return self.getArchitectureWindows() else: g.feedback.log(LogLevels.DEBUG, "Working out if we are running 32 or 64 bit") if(sys.maxsize > 2**32): g.feedback.log(LogLevels.DEBUG, "Decided 64 bit") return Architecture.x64 else: g.feedback.log(LogLevels.DEBUG, "Decided 32 bit") return Architecture.x32 """ Windows special case for getting architecture """ def getArchitectureWindows(self): from _winreg import * softwarekey = OpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE") microsoftkey = OpenKey(softwarekey, "Microsoft") windowskey = OpenKey(microsoftkey, "Windows NT") versionkey = OpenKey(windowskey, "CurrentVersion") value = QueryValueEx(versionkey, "BuildLabEx")[0] CloseKey(versionkey) CloseKey(windowskey) CloseKey(microsoftkey) CloseKey(softwarekey) if "amd64" in value: g.feedback.log(LogLevels.DEBUG, "From value %s, decided we are 64 bit" % value) return Architecture.x64 else: g.feedback.log(LogLevels.DEBUG, "From value %s, decided we are 32 bit" % value) return Architecture.x32 """ Loads the manifest file """ def loadManifest(self): g.feedback.log(LogLevels.INFO, "Loading new manifest from %s" % options.manifest) self.new_manifest = Manifest(self.os, self.arch, options.manifest, options.manifest_is_url) if self.isInstalled(): manifest_file = ".jinn" + self.sep() + "current_manifest.json" g.feedback.log(LogLevels.INFO, "Loading manifest from %s" % manifest_file) self.manifest = Manifest(self.os, self.arch, manifest_file, False, True) else: g.feedback.log(LogLevels.INFO, "Loading manifest from new manifest, as not installed") self.manifest = self.new_manifest """ A helper which sets up the system before a run """ def setupSystem(self): g.feedback.log(LogLevels.INFO, "Setting up the system") # Make sure we are installed if not self.isInstalled(): g.feedback.log(LogLevels.INFO, "We aren't installed, so installing") status = self.doInstall() if status != 0: g.feedback.log(LogLevels.ERROR, "Tried installing but failed horribly") g.feedback.userMessage("Installation failed (1) - please contact distributor") return status g.feedback.log(LogLevels.INFO, "Installation succeeded") else: self.loadManifest() return self.doUpdate() """ Runs the default action in the jinn """ def runDefaultAction(self): g.feedback.log(LogLevels.DEBUG, "Running default action") self.setupSystem() g.feedback.log(LogLevels.DEBUG, "Default action execution commencing") try: self.manifest.runDefaultAction(self.args) g.feedback.log(LogLevels.DEBUG, "Run default action executed successfully") return 0 except Exception as e: g.feedback.log(LogLevels.ERROR, "Running default action threw exception %s" % e) return 1 """ Runs a specific action within the jinn """ def runAction(self, action): g.feedback.log(LogLevels.INFO, "Running %s action" % action) self.setupSystem() g.feedback.log(LogLevels.DEBUG, "Run action %s" % action) try: self.manifest.runAction(action, self.args) g.feedback.log(LogLevels.INFO, "Running action %s successfully completed" % action) return 0 except Exception as e: g.feedback.log(LogLevels.ERROR, "Running action %s threw exception %s" % (action, e)) return 1 """ Are we in dev mode? """ def isDevMode(self): isDev = options.version is "DEV" g.feedback.log(LogLevels.WARN, "Dev mode? %s" % str(isDev)) return isDev """ Checks the manifests for updates """ def doUpdate(self): g.feedback.log(LogLevels.DEBUG, "Starting update procedure") # No update if the version number is the same if self.manifest.jinn.version == self.new_manifest.jinn.version: g.feedback.log(LogLevels.DEBUG, "New and current manifest versions are %s and %s, so skipping update as they are identical" % (self.manifest.jinn.version, self.new_manifest.jinn.version)) return True g.feedback.log(LogLevels.DEBUG, "Setting installation status across manifests") # Initially, set the resources that are installed on the new manifest already if not self.new_manifest.setInstallStatus(self.manifest.resources): g.feedback.log(LogLevels.ERROR, "Failed to set install status") return False g.feedback.log(LogLevels.INFO, "Installing new resources") # First, install resources that are new if not self.new_manifest.installNewResources(self.manifest.resources): g.feedback.log(LogLevels.ERROR, "Failed to install new resources") return False g.feedback.log(LogLevels.INFO, "Uninstalling removed resources") # Second, uninstall resources that are gone if not self.new_manifest.uninstallRemovedResources(self.manifest.resources): g.feedback.log(LogLevels.ERROR, "Removing resources failed") return False g.feedback.log(LogLevels.INFO, "Updating changed resources") # Third, update resources that are new version if not self.new_manifest.updateResources(self.manifest.resources): g.feedback.log(LogLevels.ERROR, "Updating changed resources failed") return False g.feedback.log(LogLevels.DEBUG, "Saving manifest") # Finally, transition the manifest over to the new one self.manifest = self.new_manifest if not self.manifest.save(): g.feedback.log(LogLevels.ERROR, "Unable to save updated manifest") return False # Done! g.feedback.log(LogLevels.DEBUG, "Update complete") return True """ Copy this executable to the target directory, then run it """ def doCopy(self): g.feedback.log(LogLevels.DEBUG, "We are not in the correct directory, so installing to the correct location") if self.os is OperatingSystem.OSX: g.feedback.log(LogLevels.DEBUG, "Copying in OS X mode") targetDir = self.getInstallTargetDirectory() copyTargetDir = targetDir.rsplit("/", 2)[0] currentDir = self.getCurrentDirectory() + self.sep() + ".." + self.sep() + ".." executable = targetDir + self.sep() + self.getExecutableName() g.feedback.log(LogLevels.DEBUG, "Target executable: %s" % executable) if not self.exists(executable): g.feedback.log(LogLevels.DEBUG, "Target executable does not exist, copying") if not self.makeDirectory(copyTargetDir): return False if not self.copyDir(currentDir, copyTargetDir): return False else: g.feedback.log(LogLevels.DEBUG, "Target executable exists, so running it") cmd = executable + " -install" g.feedback.log(LogLevels.DEBUG, "Executing command: %s" % cmd) res = os.system(cmd) if res < 1: g.feedback.log(LogLevels.DEBUG, "Executed command successfully") return 0 else: g.feedback.log(LogLevels.ERROR, "Executing command %s failed with code %s" % (cmd, str(res))) return 1 else: g.feedback.log(LogLevels.DEBUG, "Copying in Windows / Linux mode") targetFile = self.getInstallTargetFile() g.feedback.log(LogLevels.DEBUG, "Target file is %s" % targetFile) d = self.getInstallTargetDirectory() g.feedback.log(LogLevels.DEBUG, "Target directory is %s" % d) if not self.exists(targetFile): # Make the jinn install directory if not self.makeDirectory(d): g.feedback.log(LogLevels.ERROR, "Unable to make directory %s to install to" % d) return 1 # Copy this binary into it frm = self.getCurrentFile() to = targetFile g.feedback.log(LogLevels.DEBUG, "Copying from %s to %s" % (frm, to)) if not self.copyFile(frm, to): g.feedback.log(LogLevels.ERROR, "Unable to copy %s to %s" % (frm,to)) return 1 # Change into that directory g.feedback.log(LogLevels.DEBUG, "Changing to %s" % d) if not self.changeDirectory(d): g.feedback.log(LogLevels.ERROR, "Unable to change to the InstallTargetDirectory %s" % d) return 1 # Run the new executable g.feedback.log(LogLevels.DEBUG, "Code copied to %s, executing" % targetFile) cmd = self.getExecutableName() + " -install" if self.os == OperatingSystem.LIN or self.os == OperatingSystem.OSX: cmd = "./" + cmd g.feedback.log(LogLevels.DEBUG, "Run command: %s" % cmd) os.system(cmd) return 0 """ Runs an installation of this jinn """ def doInstall(self): g.feedback.log(LogLevels.INFO, "Beginning installation") # We need the manifest first of all self.loadManifest() # Hard code here to not happen for dev correctDir = self.isCorrectDirectory() g.feedback.log(LogLevels.DEBUG, "Are we in correct directory? %s" % str(correctDir)) if not correctDir and not self.isDevMode(): return self.doCopy() # Make sure we are in the right directory installDir = self.getInstallTargetDirectory() g.feedback.log(LogLevels.DEBUG, "Target install dir is %s" % installDir) if not self.changeDirectory(installDir) and not self.isDevMode(): g.feedback.log(LogLevels.ERROR, "Unable to change to where we thought we were installed, %s" % installDir) return 1 if self.isInstalled(): g.feedback.log(LogLevels.ERROR, "This jinn is already installed") g.feedback.userMessage("Installation failed (3) - please contact distributor") return 1 g.feedback.log(LogLevels.DEBUG, "Installing") if not self.makeDirectory(".jinn"): g.feedback.log(LogLevels.ERROR, "Unable to make .jinn directory") return 1 if not self.manifest.save(): g.feedback.log(LogLevels.ERROR, "Unable to save the manifest") return 1 try: if self.manifest.installResources(): g.feedback.log(LogLevels.DEBUG, "Install resources succeeded") return 0 else: g.feedback.log(LogLevels.ERROR, "Install resources failed") return 1 except Exception as e: g.feedback.log(LogLevels.ERROR, "Unable to install resources: %s" % e) return 1 """ Runs uninstallation """ def doUninstall(self): g.feedback.log(LogLevels.INFO, "Doing uninstallation") if not self.isInstalled(): g.feedback.log(LogLevels.ERROR, "This jinn is not installed, so cannot be uninstalled") g.feedback.userMessage("Uninstallation failed (4) - please contact distributor") return 1 g.feedback.log(LogLevels.DEBUG, "Uninstalling") self.loadManifest() try: if self.manifest.uninstallResources(): if self.delete(".jinn"): g.feedback.userMessage("Uninstallation finished. To completely erase this application, please delete the directory %s" % self.getInstallTargetDirectory()) return 0 else: g.feedback.log(LogLevels.ERROR, "Failed to delete .jinn directory, will think its still installed") return 1 else: g.feedback.log(LogLevels.ERROR, "Uninstallation failed") return 1 except Exception as e: g.feedback.log(LogLevels.ERROR, "Unable to uninstall: %s" % e) return 1 """ Returns the install target directory """ def getInstallTargetDirectory(self): if self.isDevMode(): return self.getCurrentDirectory() elif self.os is OperatingSystem.OSX: return self.getHomeDirectory() + self.sep() + "Applications" + self.sep() + self.manifest.jinn.name + ".app" + self.sep() + "Contents" + self.sep() + "MacOS" else: return self.getHomeDirectory() + self.getDirectorySeparator() + self.manifest.jinn.name """ Get the name of the executable """ def getExecutableName(self): if self.os == OperatingSystem.WIN: return self.manifest.jinn.name + ".jinn.exe" elif self.os == OperatingSystem.LIN: return self.manifest.jinn.name + ".jinn" elif self.os == OperatingSystem.OSX: return "jinn" return None """ Get the file we wish to install to """ def getInstallTargetFile(self): return self.getInstallTargetDirectory() + self.getDirectorySeparator() + self.getExecutableName() """ Check whether or not we are running from the right place """ def isCorrectDirectory(self): currentdir = self.getCurrentDirectory() targetdir = self.getInstallTargetDirectory() g.feedback.log(LogLevels.DEBUG, "Current directory: %s" % currentdir) g.feedback.log(LogLevels.DEBUG, "Target dir: %s" % targetdir) return targetdir == currentdir """ Take the sys args and turn them into a string stored on the object for later use. Offset is how many to skip off the front. Automatically skips the first one, the current script """ def processArgs(self, offset = 0): args = copy.copy(sys.argv) args.pop(0) i = 0 while i < offset: args.pop(0) i += 1 self.args = " ".join(map(str, args)) g.feedback.log(LogLevels.DEBUG, "System args: %s" % self.args) """ Check whether or not this jinn is currently installed """ def isInstalled(self): return self.directoryExists(".jinn") """ Output the version information """ def doVersion(self): g.feedback.userMessage(""" %s Version: %s """ % (self.header, options.version)) return 0 """ Output the help content """ def doHelp(self): g.feedback.userMessage(""" %s Created by import.io Options: ./jinn Run the jinn with the default action ./jinn -install Run the jinn installation ./jinn -uninstall Uninstall the jinn ./jinn -help Display this helpful help dialog ./jinn -action (actionname) Run the jinn action specified by (actionname) ./jinn -version Print the version string """ % self.header) return 0 """ Runs the jinn feature we need to perform """ def do(self): # Change to the current run directory self.changeDirectory(self.getPathFromFilePath(sys.argv[0])) # Analyse the sys args to figure out what to do if len(sys.argv) < 2: # No extra args, if we are installed we want to run the default action. # Otherwise this is the first run from download, so do install if self.isInstalled(): return self.runDefaultAction() else: return self.doInstall() elif sys.argv[1] == "-install": return self.doInstall() elif sys.argv[1] == "-uninstall": return self.doUninstall() elif sys.argv[1] == "-help": return self.doHelp() elif sys.argv[1] == "-version": return self.doVersion() elif sys.argv[1] == "-action": if len(sys.argv) < 3: g.feedback.userMessage("For -action, you must specify an action - try -help") return 1 self.processArgs(2) return self.runAction(sys.argv[2]) else: # There are some args, we don't recognise the first, so must want to run default action with some args self.processArgs() return self.runDefaultAction()