コード例 #1
0
 def preLaunch(self):
     """
     Sets ourself up for running 
     Needed for unit tests
     """
     log.debug("preLaunch")
     self.packageStore = PackageStore()
     self.ideviceStore = IdeviceStore(self.config)
     self.ideviceStore.load()
     # Make it so jelly can load objects from ~/.exe/idevices
     sys.path.append(self.config.configDir / 'idevices')
     self.webServer = WebServer(self)
     # and determine the web server's port before launching the client, so it can use the same port#:
     self.webServer.find_port()
コード例 #2
0
ファイル: application.py プロジェクト: exelearning/iteexe
    def preLaunch(self):
        """
        Sets ourself up for running
        Needed for unit tests
        """
        log.debug("preLaunch")
        self.ideviceStore = IdeviceStore(self.config)
        try:
            self.ideviceStore.load()
        except:
            backup = self.config.configDir / 'idevices.backup'
            if backup.exists():
                backup.rmtree()
            (self.config.configDir / 'idevices').move(backup)
            self.loadErrors.append(
               _(u'An error has occurred when loading your Idevice Store. A backup is saved at %s') % backup)
            self.ideviceStore.load()
        # Make it so jelly can load objects from ~/.exe/idevices
        sys.path.append(self.config.configDir/'idevices')
        self.webServer = WebServer(self, self.packagePath)
        # and determine the web server's port before launching the client, so it can use the same port#:
        self.webServer.find_port()


        # Add missing mime types to Twisted for Windows
        File.contentTypes.update({
            '.odt': 'application/vnd.oasis.opendocument.text',
            '.odp': 'application/vnd.oasis.opendocument.presentation',
            '.ods': 'application/vnd.oasis.opendocument.spreadsheet',
            '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
            '.pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
            '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            '.elp': 'application/zip'
        })
コード例 #3
0
 def preLaunch(self):
     """
     Sets ourself up for running 
     Needed for unit tests
     """
     log.debug("preLaunch")
     self.packageStore = PackageStore()
     self.ideviceStore = IdeviceStore(self.config)
     self.ideviceStore.load()
     self.webServer = WebServer(self)
コード例 #4
0
 def preLaunch(self):
     """
     Sets ourself up for running 
     Needed for unit tests
     """
     log.debug("preLaunch")
     self.packageStore = PackageStore()
     self.ideviceStore = IdeviceStore(self.config)
     self.ideviceStore.load()
     sys.path.append(self.config.configDir / "idevices")
     self.webServer = WebServer(self)
     self.webServer.find_port()
コード例 #5
0
 def preLaunch(self):
     """
     Sets ourself up for running 
     Needed for unit tests
     """
     log.debug("preLaunch")
     self.ideviceStore = IdeviceStore(self.config)
     try:
         self.ideviceStore.load()
     except:
         backup = self.config.configDir / 'idevices.backup'
         if backup.exists():
             backup.rmtree()
         (self.config.configDir / 'idevices').move(backup)
         self.loadErrors.append(
            _(u'An error has occurred when loading your Idevice Store. A backup is saved at %s') % backup)
         self.ideviceStore.load()
     # Make it so jelly can load objects from ~/.exe/idevices
     sys.path.append(self.config.configDir/'idevices')
     self.webServer = WebServer(self, self.packagePath)
     # and determine the web server's port before launching the client, so it can use the same port#:
     self.webServer.find_port()
コード例 #6
0
ファイル: application.py プロジェクト: manamani/iteexe
 def preLaunch(self):
     """
     Sets ourself up for running 
     Needed for unit tests
     """
     log.debug("preLaunch")
     self.ideviceStore = IdeviceStore(self.config)
     self.ideviceStore.load()
     # Make it so jelly can load objects from ~/.exe/idevices
     sys.path.append(self.config.configDir/'idevices')
     self.webServer = WebServer(self, self.packagePath)
     # and determine the web server's port before launching the client, so it can use the same port#:
     self.webServer.find_port()
コード例 #7
0
    def preLaunch(self):
        """
        Sets ourself up for running
        Needed for unit tests
        """
        log.debug("preLaunch")
        self.ideviceStore = IdeviceStore(self.config)
        try:
            self.ideviceStore.load()
        except:
            backup = self.config.configDir / 'idevices.backup'
            if backup.exists():
                backup.rmtree()
            (self.config.configDir / 'idevices').move(backup)
            self.loadErrors.append(
                _(u'An error has occurred when loading your Idevice Store. A backup is saved at %s'
                  ) % backup)
            self.ideviceStore.load()
        # Make it so jelly can load objects from ~/.exe/idevices
        sys.path.append(self.config.configDir / 'idevices')
        self.webServer = WebServer(self, self.packagePath)
        # and determine the web server's port before launching the client, so it can use the same port#:
        self.webServer.find_port()

        # Add missing mime types to Twisted for Windows
        File.contentTypes.update({
            '.odt':
            'application/vnd.oasis.opendocument.text',
            '.odp':
            'application/vnd.oasis.opendocument.presentation',
            '.ods':
            'application/vnd.oasis.opendocument.spreadsheet',
            '.docx':
            'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
            '.pptx':
            'application/vnd.openxmlformats-officedocument.presentationml.presentation',
            '.xlsx':
            'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        })
コード例 #8
0
class Application:
    """
    Main application class, pulls together everything and runs it.
    """

    version = 1

    def __init__(self):
        """
        Initialize
        """
        self.config       = None
        self.ideviceStore = None
        self.packagePath  = None
        self.webServer    = None
        self.standalone   = False # Used for the ready to run exe
        self.portable   = False # FM: portable mode
        self.persistNonPersistants = False  
        self.tempWebDir   = mkdtemp('.eXe')
        self.resourceDir=None
        self.afterUpgradeHandlers = []
        self.preferencesShowed = False
        self.loadErrors = []
        assert G.application is None, "You tried to instantiate two Application objects"
        G.application = self

    def main(self):
        """
        Main function, starts eXe
        """
        self.processArgs()
        self.loadConfiguration()
        installSafeTranslate()
        self.preLaunch()
        # preLaunch() has called find_port() to set config.port (the IP port #)
        self.upgrade()
        if self.config.port >= 0:
            reactor.callWhenRunning(self.launch)
            log.info('serving')
            self.serve()
            log.info('done serving')
        else:
            log.error('eXe appears to already be running')
            log.error('looks like the eXe server was not able to find a valid port; terminating...')
        shutil.rmtree(self.tempWebDir, True)

    def upgrade(self):
        """Execute all upgraToVersionX functions from stored version to actual version"""
        version_file = self.config.configDir / 'version'
        storedVersion = 0
        if version_file.exists():
            storedVersion = int(version_file.bytes())
        for v in xrange(storedVersion + 1, self.version + 1):
            method = getattr(Application, 'upgradeToVersion%d' % v, None)
            if method:
                method(self)
        version_file.write_text(str(self.version))

    def upgradeToVersion1(self):
        """Hide experimental idevices"""
        log.info('Upgrading to version 1')
        for idevice in self.ideviceStore.getIdevices():
            lower_title = idevice._title.lower()
            if self.config.idevicesCategories.get(lower_title, '') == ['Experimental']:
                self.config.hiddeniDevices.append(lower_title)
                self.config.configParser.set('idevices', lower_title, '0')

    def processArgs(self):
        """
        Processes the command line arguments
        """
        try:
            options, packages = getopt(sys.argv[1:], 
                                       "hV", ["help", "version", "standalone","portable"])
        except GetoptError:
            self.usage()
            sys.exit(2)

        log.debug('options: %s, packages: %s' % (options, packages))
        if len(packages) == 1:
            self.packagePath = packages[0]

        elif len(packages) > 1:
            self.usage()
            sys.exit(2)

        for option in options:
            if option[0] in ("-V", "--version"):
                print "eXe", version.version
                sys.exit()
            elif option[0] in ("-h", "--help"):
                self.usage()
                sys.exit()
            elif option[0].lower() == '--standalone':
                self.standalone = True
            elif option[0].lower() == '--portable':
                self.standalone = True
                self.portable = True

    
    def loadConfiguration(self):
        """
        Loads the config file and applies all the settings
        """
        if self.standalone:
            from exe.engine.standaloneconfig import StandaloneConfig
            configKlass = StandaloneConfig
        elif sys.platform[:3] == "win":
            from exe.engine.winconfig import WinConfig
            configKlass = WinConfig
        elif sys.platform[:6] == "darwin":
            from exe.engine.macconfig import MacConfig
            configKlass = MacConfig
        else:
            from exe.engine.linuxconfig import LinuxConfig
            configKlass = LinuxConfig
        try:
            self.config = configKlass()
        except:
            configPath = configKlass.getConfigPath()
            backup = configPath + '.backup'
            configPath.move(backup)
            self.config = configKlass()
            self.loadErrors.append(
               _(u'An error has occurred when loading your config. A backup is saved at %s') % backup)
        log.debug("logging set up")
        G.application.exeAppUri = 'http://localhost:%d' % (self.config.port)

    def preLaunch(self):
        """
        Sets ourself up for running 
        Needed for unit tests
        """
        log.debug("preLaunch")
        self.ideviceStore = IdeviceStore(self.config)
        try:
            self.ideviceStore.load()
        except:
            backup = self.config.configDir / 'idevices.backup'
            if backup.exists():
                backup.rmtree()
            (self.config.configDir / 'idevices').move(backup)
            self.loadErrors.append(
               _(u'An error has occurred when loading your Idevice Store. A backup is saved at %s') % backup)
            self.ideviceStore.load()
        # Make it so jelly can load objects from ~/.exe/idevices
        sys.path.append(self.config.configDir/'idevices')
        self.webServer = WebServer(self, self.packagePath)
        # and determine the web server's port before launching the client, so it can use the same port#:
        self.webServer.find_port()


    def serve(self):
        """
        Starts the web server,
        this func doesn't return until after the app has finished
        """
        print "Welcome to eXe: the EXtremely Easy to use eLearning authoring tool"
        log.info("eXe running...")
        self.webServer.run()

    def launch(self):
        """
        launches the webbrowser
        """

        if self.packagePath:
            try:
                package = Package.load(self.packagePath)
                self.webServer.root.package = package
                launchBrowser(self.config, package.name)
            except:
                self.webServer.root.packagePath = None
                launchBrowser(self.config, "")
        else:
            launchBrowser(self.config, "")

    def usage(self):
        """
        Print usage info
        """
        self.loadConfiguration()
        print _("""eXeLearning, the EXtremely Easy to use eLearning authoring tool
   Usage: %s [OPTION] [PACKAGE]
  -V, --version    print version information and exit
  -h, --help       display this help and exit
  --standalone     Run totally from current directory
  --portable       Run in portable mode
Settings are read from exe.conf in $HOME/.exe on Linux/Unix/Mac OS or
in Documents and Settings/<user name>/Application Data/exe on Windows XP or
Users/<user name>/AppData/Roaming/exe on Windows 7""") % os.path.basename(sys.argv[0])
コード例 #9
0
class Application:
    """
    Main application class, pulls together everything and runs it.
    """

    def __init__(self):
        """
        Initialize
        """
        self.config = None
        self.ideviceStore = None
        self.packagePath = None
        self.webServer = None
        self.standalone = False  # Used for the ready to run exe
        self.portable = False  # FM: portable mode
        self.persistNonPersistants = False
        self.tempWebDir = mkdtemp(".eXe")
        self.resourceDir = None
        self.afterUpgradeHandlers = []
        self.preferencesShowed = False
        self.loadErrors = []
        assert globals.application is None, "You tried to instantiate two Application objects"
        globals.application = self

    def main(self):
        """
        Main function, starts eXe
        """
        self.processArgs()
        self.loadConfiguration()
        installSafeTranslate()
        self.preLaunch()
        # preLaunch() has called find_port() to set config.port (the IP port #)
        if self.config.port >= 0:
            reactor.callWhenRunning(self.launch)
            log.info("serving")
            self.serve()
            log.info("done serving")
        else:
            # self.xulMessage(_('eXe appears to already be running'))
            log.error("eXe appears to already be running")
            log.error("looks like the eXe server was not able to find a valid port; terminating...")
        shutil.rmtree(self.tempWebDir, True)

    def processArgs(self):
        """
        Processes the command line arguments
        """
        try:
            options, packages = getopt(sys.argv[1:], "hV", ["help", "version", "standalone", "portable"])
        except GetoptError:
            self.usage()
            sys.exit(2)

        if len(packages) == 1:
            self.packagePath = packages[0]

        elif len(packages) > 1:
            self.usage()
            sys.exit(2)

        for option in options:
            if option[0] in ("-V", "--version"):
                print "eXe", version.version
                sys.exit()
            elif option[0] in ("-h", "--help"):
                self.usage()
                sys.exit()
            elif option[0].lower() == "--standalone":
                self.standalone = True
            elif option[0].lower() == "--portable":
                self.standalone = True
                self.portable = True

    def loadConfiguration(self):
        """
        Loads the config file and applies all the settings
        """
        if self.standalone:
            from exe.engine.standaloneconfig import StandaloneConfig

            configKlass = StandaloneConfig
        elif sys.platform[:3] == "win":
            from exe.engine.winconfig import WinConfig

            configKlass = WinConfig
        elif sys.platform[:6] == "darwin":
            from exe.engine.macconfig import MacConfig

            configKlass = MacConfig
        else:
            from exe.engine.linuxconfig import LinuxConfig

            configKlass = LinuxConfig
        try:
            self.config = configKlass()
        except:
            configPath = configKlass.getConfigPath()
            backup = configPath + ".backup"
            configPath.move(backup)
            self.config = configKlass()
            self.loadErrors.append(
                _(u"An error has occurred when loading your config. A backup is saved at %s") % backup
            )
        log.debug("logging set up")

    def preLaunch(self):
        """
        Sets ourself up for running 
        Needed for unit tests
        """
        log.debug("preLaunch")
        self.ideviceStore = IdeviceStore(self.config)
        try:
            self.ideviceStore.load()
        except:
            backup = self.config.configDir / "idevices.backup"
            if backup.exists():
                backup.rmtree()
            (self.config.configDir / "idevices").move(backup)
            self.loadErrors.append(
                _(u"An error has occurred when loading your Idevice Store. A backup is saved at %s") % backup
            )
            self.ideviceStore.load()
        # Make it so jelly can load objects from ~/.exe/idevices
        sys.path.append(self.config.configDir / "idevices")
        self.webServer = WebServer(self, self.packagePath)
        # and determine the web server's port before launching the client, so it can use the same port#:
        self.webServer.find_port()

    def serve(self):
        """
        Starts the web server,
        this func doesn't return until after the app has finished
        """
        print "Welcome to eXe: the eLearning XHTML editor"
        log.info("eXe running...")
        self.webServer.run()

    def launch(self):
        """
        launches the webbrowser
        """

        if self.packagePath:
            try:
                package = Package.load(self.packagePath)
                self.webServer.root.package = package
                launchBrowser(self.config, package.name)
            except:
                self.webServer.root.packagePath = None
                launchBrowser(self.config, "")
        else:
            launchBrowser(self.config, "")

    def usage(self):
        """
        Print usage info
        """
        self.loadConfiguration()
        print _(
            """Usage: %s [OPTION] [PACKAGE]
  -V, --version    print version information and exit
  -h, --help       display this help and exit
  --standalone     Run totally from current directory
  --portable       Run in portable mode
Settings are read from exe.conf in $HOME/.exe on Linux/Unix/Mac OS or
in Documents and Settings/<user name>/Application Data/exe on Windows XP or
Users/<user name>/AppData/Roaming/exe on Windows 7"""
        ) % os.path.basename(sys.argv[0])
コード例 #10
0
class Application:
    """
    Main application class, pulls together everything and runs it.
    """
    def __init__(self):
        """
        Initialize
        """
        self.config       = None
        self.packageStore = None
        self.ideviceStore = None
        self.packagePath  = None
        self.webServer    = None
        self.standalone   = False # Used for the ready to run exe
        assert globals.application is None, "You tried to instantiate two Application objects"
        globals.application = self
    def main(self):
        """
        Main function, starts eXe
        """
        self.processArgs()
        self.loadConfiguration()
        installSafeTranslate()
        self.preLaunch()
        self.launch()
        log.info('serving')
        self.serve()
        log.info('done serving')
    def processArgs(self):
        """
        Processes the command line arguments
        """
        try:
            options, packages = getopt(sys.argv[1:], 
                                       "hV", ["help", "version", "standalone"])
        except GetoptError:
            self.usage()
            sys.exit(2)
        if len(packages) == 1:
            self.packagePath = packages[0]
        elif len(packages) > 1:
            self.usage()
            sys.exit(2)
        for option in options:
            if option[0] in ("-V", "--version"):
                print "eXe", version.version
                sys.exit()
            elif option[0] in ("-h", "--help"):
                self.usage()
                sys.exit()
            elif option[0].lower() == '--standalone':
                self.standalone = True
    def loadConfiguration(self):
        """
        Loads the config file and applies all the settings
        """
        if self.standalone:
            from exe.engine.standaloneconfig import StandaloneConfig
            self.config = StandaloneConfig()
        elif sys.platform[:3] == "win":
            from exe.engine.winconfig import WinConfig
            self.config = WinConfig()
        elif sys.platform[:6] == "darwin":
            from exe.engine.macconfig import MacConfig
            self.config = MacConfig()
        else:
            from exe.engine.linuxconfig import LinuxConfig
            self.config = LinuxConfig()
        log.debug("logging set up")
    def preLaunch(self):
        """
        Sets ourself up for running 
        Needed for unit tests
        """
        log.debug("preLaunch")
        self.packageStore = PackageStore()
        self.ideviceStore = IdeviceStore(self.config)
        self.ideviceStore.load()
        sys.path.append(self.config.configDir/'idevices')
        self.webServer = WebServer(self)
    def serve(self):
        """
        Starts the web server,
        this func doesn't return until after the app has finished
        """
        print "Welcome to eXe: the eLearning XHTML editor"
        log.info("eXe running...")
        self.webServer.run()
    def _loadPackage(self, packagePath):
        """
        Convenience function for loading the first package that we'll browse to
        """
        try:
            package = self.packageStore.loadPackage(packagePath)
            log.debug("loading package "+package.name)
            self.webServer.root.bindNewPackage(package)
            launchBrowser(self.config, package.name)
            return package
        except Exception, e:
            log.error('Error loading first Package (%s): %s' % (packagePath, e))
            return None
コード例 #11
0
class Application:
    """
    Main application class, pulls together everything and runs it.
    """

    def __init__(self):
        """
        Initialize
        """
        self.config = None
        self.packageStore = None
        self.ideviceStore = None
        self.packagePath = None
        self.webServer = None
        self.standalone = False  # Used for the ready to run exe
        self.persistNonPersistants = False
        self.tempWebDir = mkdtemp(".eXe")
        self.afterUpgradeHandlers = []
        assert globals.application is None, "You tried to instantiate two Application objects"
        globals.application = self

    def main(self):
        """
        Main function, starts eXe
        """
        self.processArgs()
        self.loadConfiguration()
        eXeStart = os.path.join(os.path.dirname(globals.application.tempWebDir), "tmpExeStartupTime")
        if os.name == "posix":
            eXeStart = eXeStart + "." + str(os.getuid())
        log.debug(u"eXeStart: " + eXeStart)
        if os.path.exists(eXeStart):
            inStartFH = open(eXeStart, "r")
            lastRunTimeS = 0
            for line in inStartFH:
                lastRunTimeS = int(line)
            inStartFH.close()
            log.debug("lastRunTimeS: " + ` lastRunTimeS `)
            currentTime = int(time.time())
            currentTime2 = int(time.time())
            log.info("currentTime: " + ` currentTime `)
            if currentTime <= lastRunTimeS + 3 and currentTime >= lastRunTimeS:
                return None
        if sys.platform[:3] == "win" and self.packagePath is not None:
            self.packagePath = self.config.getLongPathName(self.packagePath)
        installSafeTranslate()
        self.preLaunch()
        if self.config.port >= 0:
            self.launch()
            log.info("serving")
            self.serve()
            log.info("done serving")
        else:
            log.error("eXe appears to already be running")
            log.error("looks like the eXe server was not able to find a valid port; terminating...")
        shutil.rmtree(self.tempWebDir, True)
        try:
            os.remove(eXeStart)
        except IOError:
            pass

    def processArgs(self):
        """
        Processes the command line arguments
        """
        try:
            options, packages = getopt(sys.argv[1:], "hV", ["help", "version", "standalone"])
        except GetoptError:
            self.usage()
            sys.exit(2)
        if len(packages) == 1:
            self.packagePath = packages[0]
        elif len(packages) > 1:
            self.usage()
            sys.exit(2)
        for option in options:
            if option[0] in ("-V", "--version"):
                print "eXe", version.version
                sys.exit()
            elif option[0] in ("-h", "--help"):
                self.usage()
                sys.exit()
            elif option[0].lower() == "--standalone":
                self.standalone = True

    def loadConfiguration(self):
        """
        Loads the config file and applies all the settings
        """
        if self.standalone:
            from exe.engine.standaloneconfig import StandaloneConfig

            self.config = StandaloneConfig()
        elif sys.platform[:3] == "win":
            from exe.engine.winconfig import WinConfig

            self.config = WinConfig()
        elif sys.platform[:6] == "darwin":
            from exe.engine.macconfig import MacConfig

            self.config = MacConfig()
        else:
            from exe.engine.linuxconfig import LinuxConfig

            self.config = LinuxConfig()
        log.debug("logging set up")

    def preLaunch(self):
        """
        Sets ourself up for running 
        Needed for unit tests
        """
        log.debug("preLaunch")
        self.packageStore = PackageStore()
        self.ideviceStore = IdeviceStore(self.config)
        self.ideviceStore.load()
        sys.path.append(self.config.configDir / "idevices")
        self.webServer = WebServer(self)
        self.webServer.find_port()

    def serve(self):
        """
        Starts the web server,
        this func doesn't return until after the app has finished
        """
        print "Welcome to eXe: the eLearning XHTML editor"
        log.info("eXe running...")
        self.webServer.run()

    def _loadPackage(self, packagePath):
        try:
            log.info("webDir: " + self.config.webDir)
            log.info("tempWebDir: " + self.tempWebDir)
            inSplashFile = self.config.webDir + "/docs/splash.xulTemplate"
            outSplashFile = self.config.webDir + "/docs/splash.xul"
            outSplashData = self.config.webDir + "/docs/splash.dat"
            outSplashFile = self.tempWebDir + "/splash.xul"
            outSplashData = self.tempWebDir + "/splash.dat"
            log.info("inSplashFile: " + inSplashFile)
            log.info("outSplashFile: " + outSplashFile)
            log.info("outSplashData: " + outSplashData)
            outSplashFH = open(outSplashData, "w")
            outSplashFH.write("")
            outSplashFH.close()
            inSplashFH = open(inSplashFile, "r")
            outSplashFH = open(outSplashFile, "w")
            pleaseWaitLoad = _(u"Please wait until loading finishes")
            for line in inSplashFH:
                line = line.replace("LOADING_FILE_NAME", packagePath)
                line = line.replace("PLEASE_WAIT_LOAD", pleaseWaitLoad)
                outSplashFH.write(line)
            inSplashFH.close()
            outSplashFH.close()
            log.info("packagePath: " + packagePath)
            launchBrowser(self.config, outSplashFile, "splash")
            shutil.copyfile(self.config.webDir + "/images/exe_logo.png", self.tempWebDir + "/exe_logo.png")
            package = self.packageStore.loadPackage(packagePath)
            port = self.config.port
            editorUrl = u"http://127.0.0.1:%d/%s" % (port, package.name)
            log.info("package.name: " + package.name)
            log.info("editorUrl: " + editorUrl)
            log.info("TempDirPath: " + editorUrl)
            outSplashFH = open(outSplashData, "w")
            outSplashFH.write("1000;" + editorUrl)
            outSplashFH.close()
            self.webServer.root.bindNewPackage(package)
            return package
        except Exception, e:
            log.error("Error loading first Package (%s): %s" % (packagePath, e))
            message = _(u"Sorry, wrong file format")
            outSplashFH = open(globals.application.tempWebDir + "/splash.dat", "w")
            message = re.sub(";", ":", message)
            port = self.config.port
            outSplashFH.write("1000;http://127.0.0.1:" + ` port ` + "/;" + message)
            outSplashFH.close()
            return None
コード例 #12
0
class Application:
    """
    Main application class, pulls together everything and runs it.
    """
    def __init__(self):
        """
        Initialize
        """
        self.config = None
        self.packageStore = None
        self.ideviceStore = None
        self.packagePath = None
        self.webServer = None
        self.standalone = False  # Used for the ready to run exe
        self.persistNonPersistants = False
        self.tempWebDir = mkdtemp('.eXe')
        self.afterUpgradeHandlers = []
        assert globals.application is None, "You tried to instantiate two Application objects"
        globals.application = self

    def main(self):
        """
        Main function, starts eXe
        """
        self.processArgs()

        self.loadConfiguration()
        try:
            username = getpass.getuser()
        except ImportError:
            username = ''
        eXeStart = globals.application.tempWebDir
        eXeStart = re.sub("[\/|\\\\][^\/|\\\\]*$", "", eXeStart)
        eXeStart = eXeStart + '/tmpExeStartupTime.' + username

        if os.path.exists(eXeStart):
            inStartFH = open(eXeStart, "r")
            lastRunTimeS = 0
            for line in inStartFH:
                try:
                    lastRunTimeS = int(line)
                except ValueError:
                    lastRunTimeS = 0
            inStartFH.close()
            log.debug('lastRunTimeS: ' + ` lastRunTimeS `)

            currentTime = int(time.time())
            currentTime2 = int(time.time())
            log.info('currentTime: ' + ` currentTime `)
            if (currentTime <= lastRunTimeS + 3
                    and currentTime >= lastRunTimeS):
                #self.xulMessage(_('eXe appears to already be running'))
                #log.info('eXe appears to already be running: <html:br/>lastRunTimes: ' + `lastRunTimeS` + '<html:br/> currentTime: ' + `currentTime` + '<html:br/>currentTime2: ' + `currentTime2`)
                return None

        else:
            log.info('eXeStart: ' + eXeStart)
            log.info('tempWebDir: ' + globals.application.tempWebDir)

        # if a document was double clicked to launch on Win32,
        #   make sure we have the long pathname
        if sys.platform[:3] == "win" and self.packagePath is not None:
            self.packagePath = self.config.getLongPathName(self.packagePath)

        installSafeTranslate()
        self.preLaunch()
        # preLaunch() has called find_port() to set config.port (the IP port #)
        if self.config.port >= 0:
            self.launch()
            log.info('serving')
            self.serve()
            log.info('done serving')
        else:
            #self.xulMessage(_('eXe appears to already be running'))
            log.error('eXe appears to already be running')
            log.error(
                'looks like the eXe server was not able to find a valid port; terminating...'
            )
        shutil.rmtree(self.tempWebDir, True)
        try:
            os.remove(eXeStart)
        except OSError:
            pass

    def processArgs(self):
        """
        Processes the command line arguments
        """
        try:
            options, packages = getopt(sys.argv[1:], "hV",
                                       ["help", "version", "standalone"])
        except GetoptError:
            self.usage()
            sys.exit(2)

        if len(packages) == 1:
            self.packagePath = packages[0]

        elif len(packages) > 1:
            self.usage()
            sys.exit(2)

        for option in options:
            if option[0] in ("-V", "--version"):
                print "eXe", version.version
                sys.exit()
            elif option[0] in ("-h", "--help"):
                self.usage()
                sys.exit()
            elif option[0].lower() == '--standalone':
                self.standalone = True

    def loadConfiguration(self):
        """
        Loads the config file and applies all the settings
        """
        if self.standalone:
            from exe.engine.standaloneconfig import StandaloneConfig
            self.config = StandaloneConfig()
        elif sys.platform[:3] == "win":
            from exe.engine.winconfig import WinConfig
            self.config = WinConfig()
        elif sys.platform[:6] == "darwin":
            from exe.engine.macconfig import MacConfig
            self.config = MacConfig()
        else:
            from exe.engine.linuxconfig import LinuxConfig
            self.config = LinuxConfig()
        log.debug("logging set up")

    def preLaunch(self):
        """
        Sets ourself up for running 
        Needed for unit tests
        """
        log.debug("preLaunch")
        self.packageStore = PackageStore()
        self.ideviceStore = IdeviceStore(self.config)
        self.ideviceStore.load()
        # Make it so jelly can load objects from ~/.exe/idevices
        sys.path.append(self.config.configDir / 'idevices')
        self.webServer = WebServer(self)
        # and determine the web server's port before launching the client, so it can use the same port#:
        self.webServer.find_port()

    def serve(self):
        """
        Starts the web server,
        this func doesn't return until after the app has finished
        """
        print "Welcome to eXe: the eLearning XHTML editor"
        log.info("eXe running...")
        self.webServer.run()

    def _loadPackage(self, packagePath):
        #"""
        #Convenience function for loading the first package that we'll browse to
        #"""
        try:
            #XXXX xxxx
            log.info("webDir: " + self.config.webDir)
            log.info("tempWebDir: " + self.tempWebDir)
            inSplashFile = self.config.webDir + "/docs/splash.xulTemplate"

            outSplashFile = self.config.webDir + "/docs/splash.xul"
            outSplashData = self.config.webDir + "/docs/splash.dat"

            outSplashFile = self.tempWebDir + "/splash.xul"
            outSplashData = self.tempWebDir + "/splash.dat"

            log.info("inSplashFile: " + inSplashFile)
            log.info("outSplashFile: " + outSplashFile)
            log.info("outSplashData: " + outSplashData)

            #resets any splash page data
            outSplashFH = open(outSplashData, "w")
            outSplashFH.write("")
            outSplashFH.close()

            inSplashFH = open(inSplashFile, "r")
            outSplashFH = open(outSplashFile, "w")
            pleaseWaitLoad = _(u'Please wait until loading finishes')
            for line in inSplashFH:
                line = line.replace("LOADING_FILE_NAME", packagePath)
                try:
                    # this can fail in non UTF-8 uris
                    line = line.replace("PLEASE_WAIT_LOAD", pleaseWaitLoad)
                except:
                    pass
                outSplashFH.write(line)
            inSplashFH.close()
            outSplashFH.close()

            log.info("packagePath: " + packagePath)

            launchBrowser(self.config, outSplashFile, "splash")
            shutil.copyfile(self.config.webDir + '/images/exe_logo.png',
                            self.tempWebDir + '/exe_logo.png')

            package = self.packageStore.loadPackage(packagePath)
            port = self.config.port
            editorUrl = u'http://127.0.0.1:%d/%s' % (port, package.name)
            log.info("package.name: " + package.name)
            log.info("editorUrl: " + editorUrl)
            log.info("TempDirPath: " + editorUrl)
            outSplashFH = open(outSplashData, "w")
            outSplashFH.write("1000;" + editorUrl)
            outSplashFH.close()

            self.webServer.root.bindNewPackage(package)
            return package

        except Exception, e:
            log.error('Error loading first Package (%s): %s' %
                      (packagePath, e))
            message = _(u'Sorry, wrong file format')

            outSplashFH=open(globals.application.tempWebDir + \
                               '/splash.dat',"w")
            message = re.sub(";", ":", message)
            port = self.config.port
            outSplashFH.write("1000;http://127.0.0.1:" + `port` + "/;" + \
                               message)
            outSplashFH.close()

            return None
コード例 #13
0
class Application:
    """
    Main application class, pulls together everything and runs it.
    """
    def __init__(self):
        """
        Initialize
        """
        global application
        self.config       = None
        self.packageStore = None
        self.ideviceStore = None
        self.packagePath  = None
        self.webServer    = None
        self.standalone   = False # Used for the ready to run exe
        assert application is None, "You tried to instantiate two Application objects"
        application = self
    def main(self):
        """
        Main function, starts eXe
        """
        self.processArgs()
        self.loadConfiguration()
        self.preLaunch()
        self.launch()
        log.info('serving')
        self.serve()
        log.info('done serving')
    def processArgs(self):
        """
        Processes the command line arguments
        """
        try:
            options, packages = getopt(sys.argv[1:], 
                                       "hV", ["help", "version", "standalone"])
        except GetoptError:
            self.usage()
            sys.exit(2)
        if len(packages) == 1:
            self.packagePath = packages[0]
        elif len(packages) > 1:
            self.usage()
            sys.exit(2)
        for option in options:
            if option[0] in ("-V", "--version"):
                print "eXe", version.version
                sys.exit()
            elif option[0] in ("-h", "--help"):
                self.usage()
                sys.exit()
            elif option[0].lower() == '--standalone':
                self.standalone = True
    def loadConfiguration(self):
        """
        Loads the config file and applies all the settings
        """
        if self.standalone:
            from exe.engine.standaloneconfig import StandaloneConfig
            self.config = StandaloneConfig()
        elif sys.platform[:3] == "win":
            from exe.engine.winconfig import WinConfig
            self.config = WinConfig()
        elif sys.platform[:6] == "darwin":
            from exe.engine.macconfig import MacConfig
            self.config = MacConfig()
        else:
            from exe.engine.linuxconfig import LinuxConfig
            self.config = LinuxConfig()
        log.debug("logging set up")
    def preLaunch(self):
        """
        Sets ourself up for running 
        Needed for unit tests
        """
        log.debug("preLaunch")
        self.packageStore = PackageStore()
        self.ideviceStore = IdeviceStore(self.config)
        self.ideviceStore.load()
        sys.path.append(self.config.configDir/'idevices')
        self.webServer = WebServer(self)
    def serve(self):
        """
        Starts the web server,
        this func doesn't return until after the app has finished
        """
        print "Welcome to eXe: the eLearning XHTML editor"
        log.info("eXe running...")
        self.webServer.run()
    def launch(self):
        """
        launches the webbrowser
        """
        if self.packagePath:
            package = self.packageStore.loadPackage(self.packagePath)
            log.debug("loading package "+package.name)
            self.webServer.root.bindNewPackage(package)
            launchBrowser(self.config, package.name)
        else:
            launchBrowser(self.config, "")
    def usage(self):
        """
        Print usage info
        """
        print "Usage: "+os.path.basename(sys.argv[0])+" [OPTION] [PACKAGE]"
        print "  -V, --version    print version information and exit"
        print "  -h, --help       display this help and exit"
        print "  --standalone     Run totally from current directory"
        print "Settings are read from exe.conf "
        print "in $HOME/.exe on Linux/Unix or"
        print "in Documents and Settings/<user name>/Application Data/exe "
        print "on Windows"
コード例 #14
0
ファイル: application.py プロジェクト: erral/iteexe
class Application:
    """
    Main application class, pulls together everything and runs it.
    """

    def __init__(self):
        """
        Initialize
        """
        self.config       = None
        self.packageStore = None
        self.ideviceStore = None
        self.packagePath  = None
        self.webServer    = None
        self.standalone   = False # Used for the ready to run exe
        self.persistNonPersistants = False  
        self.tempWebDir   = mkdtemp('.eXe')
        self.afterUpgradeHandlers = []
        assert globals.application is None, "You tried to instantiate two Application objects"
        globals.application = self

    def main(self):
        """
        Main function, starts eXe
        """
        self.processArgs()

        self.loadConfiguration()
        try:
            username = getpass.getuser()
        except ImportError:
            username = ''
        eXeStart = globals.application.tempWebDir
        eXeStart = re.sub("[\/|\\\\][^\/|\\\\]*$","",eXeStart)
        eXeStart = eXeStart + '/tmpExeStartupTime.' + username

        if os.path.exists(eXeStart):
            inStartFH=open(eXeStart, "r")
            lastRunTimeS = 0
            for line in inStartFH:
                try:
                    lastRunTimeS = int(line)
                except ValueError:
                    lastRunTimeS = 0
            inStartFH.close()
            log.debug('lastRunTimeS: ' + `lastRunTimeS`)

            currentTime = int (time.time())
            currentTime2 = int (time.time())
            log.info('currentTime: ' + `currentTime`)
            if(currentTime <= lastRunTimeS + 3 and currentTime >= lastRunTimeS):
                #self.xulMessage(_('eXe appears to already be running'))
                #log.info('eXe appears to already be running: <html:br/>lastRunTimes: ' + `lastRunTimeS` + '<html:br/> currentTime: ' + `currentTime` + '<html:br/>currentTime2: ' + `currentTime2`)
                return None

        else:
            log.info('eXeStart: ' + eXeStart)
            log.info('tempWebDir: ' + globals.application.tempWebDir)

        # if a document was double clicked to launch on Win32,
        #   make sure we have the long pathname
        if sys.platform[:3] == "win" and self.packagePath is not None:
            self.packagePath = self.config.getLongPathName(self.packagePath)

        installSafeTranslate()
        self.preLaunch()
        # preLaunch() has called find_port() to set config.port (the IP port #)
        if self.config.port >= 0:
            self.launch()
            log.info('serving')
            self.serve()
            log.info('done serving')
        else:
            #self.xulMessage(_('eXe appears to already be running'))
            log.error('eXe appears to already be running')
            log.error('looks like the eXe server was not able to find a valid port; terminating...')
        shutil.rmtree(self.tempWebDir, True)
        try:
            os.remove(eXeStart)
        except OSError:
            pass

    def processArgs(self):
        """
        Processes the command line arguments
        """
        try:
            options, packages = getopt(sys.argv[1:], 
                                       "hV", ["help", "version", "standalone"])
        except GetoptError:
            self.usage()
            sys.exit(2)

        if len(packages) == 1:
            self.packagePath = packages[0]

        elif len(packages) > 1:
            self.usage()
            sys.exit(2)

        for option in options:
            if option[0] in ("-V", "--version"):
                print "eXe", version.version
                sys.exit()
            elif option[0] in ("-h", "--help"):
                self.usage()
                sys.exit()
            elif option[0].lower() == '--standalone':
                self.standalone = True

    
    def loadConfiguration(self):
        """
        Loads the config file and applies all the settings
        """
        if self.standalone:
            from exe.engine.standaloneconfig import StandaloneConfig
            self.config = StandaloneConfig()
        elif sys.platform[:3] == "win":
            from exe.engine.winconfig import WinConfig
            self.config = WinConfig()
        elif sys.platform[:6] == "darwin":
            from exe.engine.macconfig import MacConfig
            self.config = MacConfig()
        else:
            from exe.engine.linuxconfig import LinuxConfig
            self.config = LinuxConfig()
        log.debug("logging set up")


    def preLaunch(self):
        """
        Sets ourself up for running 
        Needed for unit tests
        """
        log.debug("preLaunch")
        self.packageStore = PackageStore()
        self.ideviceStore = IdeviceStore(self.config)
        self.ideviceStore.load()
        # Make it so jelly can load objects from ~/.exe/idevices
        sys.path.append(self.config.configDir/'idevices')
        self.webServer = WebServer(self)
        # and determine the web server's port before launching the client, so it can use the same port#:
        self.webServer.find_port()


    def serve(self):
        """
        Starts the web server,
        this func doesn't return until after the app has finished
        """
        print "Welcome to eXe: the eLearning XHTML editor"
        log.info("eXe running...")
        self.webServer.run()

    def _loadPackage(self, packagePath):
        #"""
        #Convenience function for loading the first package that we'll browse to
        #"""
        try:
            #XXXX xxxx
            log.info("webDir: " + self.config.webDir)
            log.info("tempWebDir: " + self.tempWebDir)
            inSplashFile =  self.config.webDir + "/docs/splash.xulTemplate"

            outSplashFile = self.config.webDir + "/docs/splash.xul"
            outSplashData = self.config.webDir + "/docs/splash.dat"

            outSplashFile = self.tempWebDir + "/splash.xul"
            outSplashData = self.tempWebDir + "/splash.dat"

            log.info("inSplashFile: " + inSplashFile)
            log.info("outSplashFile: " + outSplashFile)
            log.info("outSplashData: " + outSplashData)

            #resets any splash page data
            outSplashFH = open(outSplashData, "w")
            outSplashFH.write("")
            outSplashFH.close()

            inSplashFH = open(inSplashFile, "r")
            outSplashFH = open(outSplashFile, "w")
            pleaseWaitLoad = _(u'Please wait until loading finishes')
            for line in inSplashFH:
                line = line.replace("LOADING_FILE_NAME", packagePath)
                try:
                    # this can fail in non UTF-8 uris
                    line = line.replace("PLEASE_WAIT_LOAD", pleaseWaitLoad)
                except:
                    pass
                outSplashFH.write(line)
            inSplashFH.close()
            outSplashFH.close()
   
            log.info("packagePath: " + packagePath)

            launchBrowser(self.config, outSplashFile, "splash")
            shutil.copyfile(self.config.webDir + '/images/exe_logo.png', 
                                      self.tempWebDir + '/exe_logo.png')

            package = self.packageStore.loadPackage(packagePath)
            port = self.config.port
            editorUrl = u'http://127.0.0.1:%d/%s' % (port, package.name)
            log.info("package.name: "+package.name)
            log.info("editorUrl: " + editorUrl)
            log.info("TempDirPath: " + editorUrl)
            outSplashFH = open(outSplashData, "w")
            outSplashFH.write("1000;" + editorUrl)
            outSplashFH.close()

            self.webServer.root.bindNewPackage(package)
            return package

        except Exception, e:
            log.error('Error loading first Package (%s): %s' % (packagePath, e))
            message = _(u'Sorry, wrong file format')

            outSplashFH=open(globals.application.tempWebDir + \
                               '/splash.dat',"w")
            message = re.sub(";",":",message)
            port = self.config.port
            outSplashFH.write("1000;http://127.0.0.1:" + `port` + "/;" + \
                               message)
            outSplashFH.close()

            return None
コード例 #15
0
ファイル: application.py プロジェクト: manamani/iteexe
class Application:
    """
    Main application class, pulls together everything and runs it.
    """

    def __init__(self):
        """
        Initialize
        """
        self.config       = None
        self.ideviceStore = None
        self.packagePath  = None
        self.webServer    = None
        self.standalone   = False # Used for the ready to run exe
        self.persistNonPersistants = False  
        self.tempWebDir   = mkdtemp('.eXe')
        self.afterUpgradeHandlers = []
        assert globals.application is None, "You tried to instantiate two Application objects"
        globals.application = self

    def main(self):
        """
        Main function, starts eXe
        """
        self.processArgs()

        self.loadConfiguration()

        # if a document was double clicked to launch on Win32,
        #   make sure we have the long pathname
        if sys.platform[:3] == "win" and self.packagePath is not None:
            self.packagePath = self.config.getLongPathName(self.packagePath)

        installSafeTranslate()
        self.preLaunch()
        # preLaunch() has called find_port() to set config.port (the IP port #)
        if self.config.port >= 0:
            reactor.callWhenRunning(self.launch)
            log.info('serving')
            self.serve()
            log.info('done serving')
        else:
            #self.xulMessage(_('eXe appears to already be running'))
            log.error('eXe appears to already be running')
            log.error('looks like the eXe server was not able to find a valid port; terminating...')
        shutil.rmtree(self.tempWebDir, True)

    def processArgs(self):
        """
        Processes the command line arguments
        """
        try:
            options, packages = getopt(sys.argv[1:], 
                                       "hV", ["help", "version", "standalone"])
        except GetoptError:
            self.usage()
            sys.exit(2)

        if len(packages) == 1:
            self.packagePath = packages[0]

        elif len(packages) > 1:
            self.usage()
            sys.exit(2)

        for option in options:
            if option[0] in ("-V", "--version"):
                print "eXe", version.version
                sys.exit()
            elif option[0] in ("-h", "--help"):
                self.usage()
                sys.exit()
            elif option[0].lower() == '--standalone':
                self.standalone = True

    
    def loadConfiguration(self):
        """
        Loads the config file and applies all the settings
        """
        if self.standalone:
            from exe.engine.standaloneconfig import StandaloneConfig
            self.config = StandaloneConfig()
        elif sys.platform[:3] == "win":
            from exe.engine.winconfig import WinConfig
            self.config = WinConfig()
        elif sys.platform[:6] == "darwin":
            from exe.engine.macconfig import MacConfig
            self.config = MacConfig()
        else:
            from exe.engine.linuxconfig import LinuxConfig
            self.config = LinuxConfig()
        log.debug("logging set up")


    def preLaunch(self):
        """
        Sets ourself up for running 
        Needed for unit tests
        """
        log.debug("preLaunch")
        self.ideviceStore = IdeviceStore(self.config)
        self.ideviceStore.load()
        # Make it so jelly can load objects from ~/.exe/idevices
        sys.path.append(self.config.configDir/'idevices')
        self.webServer = WebServer(self, self.packagePath)
        # and determine the web server's port before launching the client, so it can use the same port#:
        self.webServer.find_port()


    def serve(self):
        """
        Starts the web server,
        this func doesn't return until after the app has finished
        """
        print "Welcome to eXe: the eLearning XHTML editor"
        log.info("eXe running...")
        self.webServer.run()

    def launch(self):
        """
        launches the webbrowser
        """

        if self.packagePath:
            try:
                package = Package.load(self.packagePath)
                self.webServer.root.package = package
                launchBrowser(self.config, package.name)
            except:
                self.webServer.root.packagePath = None
                launchBrowser(self.config, "")
        else:
            launchBrowser(self.config, "")

    def usage(self):
        """
        Print usage info
        """
        print "Usage: "+os.path.basename(sys.argv[0])+" [OPTION] [PACKAGE]"
        print "  -V, --version    print version information and exit"
        print "  -h, --help       display this help and exit"
        print "  --standalone     Run totally from current directory"
        print "Settings are read from exe.conf "
        print "in $HOME/.exe on Linux/Unix or"
        print "in Documents and Settings/<user name>/Application Data/exe "
        print "on Windows"
コード例 #16
0
ファイル: application.py プロジェクト: smmartinezlujan/iteexe
class Application:
    """
    Main application class, pulls together everything and runs it.
    """

    # Responsible for the execution of the functions upgrade_to_version_x
    # Upload version file to '2'
    # It is necessary to edit the value in each update if we want it to execute
    #   the functions upgrade_to_version_x
    # They also run, obviously, if the 'configDir/version' file does not exist
    version = 2

    def __init__(self):
        """
        Initialize
        """
        self.config = None
        self.ideviceStore = None
        self.packagePath = None
        self.webServer = None
        self.exeAppUri = None
        self.standalone = False  # Used for the ready to run exe
        self.snap = False  #  Used for the Snap package
        self.portable = False  # FM: portable mode
        self.persistNonPersistants = False
        self.tempWebDir = mkdtemp('.eXe')
        self.resourceDir = None
        self.afterUpgradeHandlers = []
        self.preferencesShowed = False
        self.newVersionWarningShowed = False
        self.loadErrors = []
        assert G.application is None, "You tried to instantiate two Application objects"
        G.application = self

    def main(self):
        """
        Main function, starts eXe
        """
        self.processArgs()
        self.loadConfiguration()
        installSafeTranslate()
        self.preLaunch()
        # preLaunch() has called find_port() to set config.port (the IP port #)
        self.exeAppUri = 'http://localhost:%d' % self.config.port
        self.upgrade()
        if self.config.port >= 0:
            reactor.callWhenRunning(self.launch)
            log.info('serving')
            self.serve()
            log.info('done serving')
        else:
            log.error('eXe appears to already be running')
            log.error(
                'looks like the eXe server was not able to find a valid port; terminating...'
            )
        shutil.rmtree(self.tempWebDir, True)

    def upgrade(self):
        """Execute all upgrade_to_version_X functions from stored version to actual version"""
        version_file = self.config.configDir / 'version'
        stored_version = 0

        if version_file.exists():
            # Try to read version from file, if that fails assume 0
            try:
                stored_version = int(version_file.bytes())
            except:
                stored_version = 0

        # Execute upgrade_to_version_x (if they exist) until we reach current version
        for v in xrange(stored_version + 1, self.version + 1):
            method = getattr(Application, 'upgrade_to_version_%d' % v, None)
            if method:
                method(self)

        version_file.write_text(str(self.version))

    def upgrade_to_version_1(self):
        """Hide experimental idevices"""
        log.info('Upgrading to version 1')

        # Go through all iDevices and hide them if the category is Experimental or they are old
        iDevicesToHide = [
            'reflection', 'case study', 'image magnifier', 'wiki article',
            'external web site', 'rss', 'java applet', 'reading activity',
            'objectives', 'preknowledge', 'activity', 'free text'
        ]
        for idevice in self.ideviceStore.getIdevices():
            lower_title = idevice._title.lower()
            if self.config.idevicesCategories.get(lower_title, '') == [
                    'Experimental'
            ] or lower_title in iDevicesToHide:
                if lower_title not in self.config.hiddeniDevices:
                    self.config.hiddeniDevices.append(lower_title)
                    self.config.configParser.set('idevices', lower_title, '0')

    def upgrade_to_version_2(self):
        # In the update of version 2 we want to do the same as 'upgrade_to_version_1'
        # Old iDevices must be hidden again
        self.upgrade_to_version_1()

    def processArgs(self):
        """
        Processes the command line arguments
        """
        try:
            possibles_args = [
                "help", "version", "standalone", "portable", "snap"
            ]
            options, packages = getopt(sys.argv[1:], "hV", possibles_args)
        except GetoptError:
            self.usage()
            sys.exit(2)

        log.debug('options: %s, packages: %s' % (options, packages))
        if len(packages) == 1:
            self.packagePath = packages[0]

        elif len(packages) > 1:
            self.usage()
            sys.exit(2)

        for option in options:
            if option[0] in ("-V", "--version"):
                print "eXe", version.version
                sys.exit()
            elif option[0] in ("-h", "--help"):
                self.usage()
                sys.exit()
            elif option[0].lower() == '--standalone':
                self.standalone = True
            elif option[0].lower() == '--portable':
                self.standalone = True
                self.portable = True
            elif option[0].lower() == '--snap':
                self.snap = True

    def loadConfiguration(self):
        """
        Loads the config file and applies all the settings
        """
        if self.standalone:
            from exe.engine.standaloneconfig import StandaloneConfig
            configKlass = StandaloneConfig
        elif self.snap:
            from exe.engine.snapconfig import SnapConfig
            configKlass = SnapConfig
        elif sys.platform[:3] == "win":
            from exe.engine.winconfig import WinConfig
            configKlass = WinConfig
        elif sys.platform[:6] == "darwin":
            from exe.engine.macconfig import MacConfig
            configKlass = MacConfig
        else:
            from exe.engine.linuxconfig import LinuxConfig
            configKlass = LinuxConfig

        try:
            self.config = configKlass()
        except:
            configPath = configKlass.getConfigPath()
            backup = configPath + '.backup'
            configPath.move(backup)
            self.config = configKlass()
            self.loadErrors.append(
                _(u'An error has occurred when loading your config. A backup is saved at %s'
                  ) % backup)
        log.debug("logging set up")

    def preLaunch(self):
        """
        Sets ourself up for running
        Needed for unit tests
        """
        log.debug("preLaunch")
        self.ideviceStore = IdeviceStore(self.config)
        try:
            self.ideviceStore.load()
        except:
            backup = self.config.configDir / 'idevices.backup'
            if backup.exists():
                backup.rmtree()
            (self.config.configDir / 'idevices').move(backup)
            self.loadErrors.append(
                _(u'An error has occurred when loading your Idevice Store. A backup is saved at %s'
                  ) % backup)
            self.ideviceStore.load()
        # Make it so jelly can load objects from ~/.exe/idevices
        sys.path.append(self.config.configDir / 'idevices')
        self.webServer = WebServer(self, self.packagePath)
        # and determine the web server's port before launching the client, so it can use the same port#:
        self.webServer.find_port()

        # Add missing mime types to Twisted for Windows
        File.contentTypes.update({
            '.odt': 'application/vnd.oasis.opendocument.text',
            '.odp': 'application/vnd.oasis.opendocument.presentation',
            '.ods': 'application/vnd.oasis.opendocument.spreadsheet',
            '.docx':
            'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
            '.pptx':
            'application/vnd.openxmlformats-officedocument.presentationml.presentation',
            '.xlsx':
            'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            '.elp': 'application/zip',
            '.webm': 'video/webm'
        })

    def serve(self):
        """
        Starts the web server,
        this func doesn't return until after the app has finished
        """
        print "Welcome to eXe: the EXtremely Easy to use eLearning authoring tool"
        log.info("eXe running...")
        self.webServer.run()

    def launch(self):
        """
        launches the webbrowser
        """

        if self.packagePath:
            try:
                package = Package.load(self.packagePath)
                self.webServer.root.package = package
                launchBrowser(self.config, package.name)
            except:
                self.webServer.root.packagePath = None
                launchBrowser(self.config, "")
        else:
            launchBrowser(self.config, "")

    def usage(self):
        """
        Print usage info
        """
        self.loadConfiguration()
        print _(
            """eXeLearning, the EXtremely Easy to use eLearning authoring tool
   Usage: %s [OPTION] [PACKAGE]
  -V, --version    print version information and exit
  -h, --help       display this help and exit
  --standalone     Run totally from current directory
  --portable       Run in portable mode
Settings are read from exe.conf in $HOME/.exe on Linux/Unix/Mac OS or
in Documents and Settings/<user name>/Application Data/exe on Windows XP or
Users/<user name>/AppData/Roaming/exe on Windows 7/8/10""") % os.path.basename(
                sys.argv[0])