Example #1
0
 def import_plugin_from_zip(cls, archive):
     """
     Import a plugin from the given zip archive:
     * Lookup for the plugin .spec configuration file.
     * Search for the module where the plugin is implemented.
     * Search for the class implementing the plugin.
     * Import the plugin module.
     :type archive: str
     :rtype: tuple
     """
     if fexists(archive) and File.forPath(archive) is File.Zip:
         zf = ZipFile(archive)
         zf_name_list = zf.namelist()
         for file_or_directory in zf_name_list:
             if file_or_directory.endswith('plugin.spec'):
                 try:
                     #LOGGER.debug('Found plugin .spec: %s', os.path.join(archive, file_or_directory))
                     plugin_spec_content = zf.read(file_or_directory).decode('utf8')
                     plugin_spec = PluginManager.spec(plugin_spec_content)
                     plugin_name = plugin_spec.get('plugin', 'id')
                     plugin_zip_base_path = rstrip(file_or_directory, 'plugin.spec')
                     plugin_abs_base_path = os.path.join(archive, plugin_zip_base_path)
                     plugin_zip_module_base_path = os.path.join(plugin_zip_base_path, plugin_name)
                     plugin_abs_module_base_path = os.path.join(archive, plugin_zip_module_base_path)
                     for extension in ('.pyc', '.pyo', '.py'):
                         plugin_zip_module_path = '%s%s' % (plugin_zip_module_base_path, extension)
                         if plugin_zip_module_path in zf_name_list:
                             #LOGGER.debug('Found plugin module: %s', os.path.join(archive, plugin_zip_module_path))
                             plugin_module = zipimporter(plugin_abs_base_path).load_module(plugin_name)
                             plugin_class = PluginManager.find_class(plugin_module, plugin_name)
                             return plugin_spec, plugin_class
                     else:
                         raise PluginError('missing plugin module: %s.py(c|o)' % plugin_abs_module_base_path)
                 except Exception as e:
                     LOGGER.exception('Failed to import plugin: %s', e)
Example #2
0
 def import_reasoner_from_zip(cls, archive):
     """
     Import a reasoner from the given zip archive:
     * Lookup for the reasoner .spec configuration file.
     * Search for the module where the reasoner is implemented.
     * Search for the class implementing the reasoner.
     * Import the reasoner module.
     :type archive: str
     :rtype: tuple
     """
     if fexists(archive) and File.forPath(archive) is File.Zip:
         zf = ZipFile(archive)
         zf_name_list = zf.namelist()
         for file_or_directory in zf_name_list:
             if file_or_directory.endswith('reasoner.spec'):
                 try:
                     #LOGGER.debug('Found reasoner .spec: %s', os.path.join(archive, file_or_directory))
                     reasoner_spec_content = zf.read(file_or_directory).decode('utf8')
                     reasoner_spec = ReasonerManager.spec(reasoner_spec_content)
                     reasoner_name = reasoner_spec.get('reasoner', 'id')
                     reasoner_zip_base_path = rstrip(file_or_directory, 'reasoner.spec')
                     reasoner_abs_base_path = os.path.join(archive, reasoner_zip_base_path)
                     reasoner_zip_module_base_path = os.path.join(reasoner_zip_base_path, reasoner_name)
                     reasoner_abs_module_base_path = os.path.join(archive, reasoner_zip_module_base_path)
                     for extension in ('.pyc', '.pyo', '.py'):
                         reasoner_zip_module_path = '%s%s' % (reasoner_zip_module_base_path, extension)
                         if reasoner_zip_module_path in zf_name_list:
                             #LOGGER.debug('Found reasoner module: %s', os.path.join(archive, reasoner_zip_module_path))
                             reasoner_module = zipimporter(reasoner_abs_base_path).load_module(reasoner_name)
                             reasoner_class = ReasonerManager.find_class(reasoner_module, reasoner_name)
                             return reasoner_spec, reasoner_class
                     else:
                         raise ReasonerError('missing reasoner module: %s.py(c|o)' % reasoner_abs_module_base_path)
                 except Exception as e:
                     LOGGER.exception('Failed to import reasoner: %s', e)
Example #3
0
 def import_plugin_from_zip(self, archive):
     """
     Import a plugin from the given zip archive:
     * Lookup for the plugin .spec configuration file.
     * Search for the module where the plugin is implemented.
     * Search for the class implementing the plugin.
     * Import the plugin module.
     :type archive: str
     """
     if fexists(archive) and File.forPath(archive) is File.Zip:
         zf = ZipFile(archive)
         zf_name_list = zf.namelist()
         for file_or_directory in zf_name_list:
             if file_or_directory.endswith('plugin.spec'):
                 try:
                     LOGGER.debug('Found plugin .spec: %s', os.path.join(archive, file_or_directory))
                     plugin_spec_content = zf.read(file_or_directory).decode('utf8')
                     plugin_spec = self.spec(plugin_spec_content)
                     plugin_name = plugin_spec.get('plugin', 'id')
                     plugin_zip_base_path = rstrip(file_or_directory, 'plugin.spec')
                     plugin_abs_base_path = os.path.join(archive, plugin_zip_base_path)
                     plugin_zip_module_base_path = os.path.join(plugin_zip_base_path, plugin_name)
                     plugin_abs_module_base_path = os.path.join(archive, plugin_zip_module_base_path)
                     for extension in ('.pyc', '.pyo', '.py'):
                         plugin_zip_module_path = '%s%s' % (plugin_zip_module_base_path, extension)
                         if plugin_zip_module_path in zf_name_list:
                             LOGGER.debug('Found plugin module: %s', os.path.join(archive, plugin_zip_module_path))
                             plugin_module = zipimporter(plugin_abs_base_path).load_module(plugin_name)
                             plugin_class = self.find_class(plugin_module, plugin_name)
                             return plugin_spec, plugin_class
                     else:
                         raise PluginError('missing plugin module: %s.py(c|o)' % plugin_abs_module_base_path)
                 except Exception as e:
                     LOGGER.exception('Failed to import plugin: %s', e)
Example #4
0
    def install(self, archive):
        """
        Install the given plugin archive.
        During the installation process we'll check for a correct plugin structure,
        i.e. for the .spec file and the plugin module to be available. We won't check if
        the plugin actually runs since this will be handle by the application start sequence.

        :type archive: str
        :rtype: PluginSpec
        """
        try:
            # CHECK FOR CORRECT PLUGIN ARCHIVE
            if not fexists(archive):
                raise PluginError('file not found: %s' % archive)
            if not File.forPath(archive) is File.Zip:
                raise PluginError('%s is not a valid plugin' % archive)

            # LOOKUP THE SPEC FILE
            zf = ZipFile(archive)
            zf_name_list = zf.namelist()
            if 'plugin.spec' in zf_name_list:
                LOGGER.debug('Found plugin .spec: %s', os.path.join(archive, 'plugin.spec'))
                plugin_spec_content = zf.read('plugin.spec').decode('utf8')
                plugin_spec = self.spec(plugin_spec_content)
            else:
                raise PluginError('missing plugin.spec in %s' % archive)

            # LOOKUP THE PLUGIN MODULE
            plugin_name = plugin_spec.get('plugin', 'id')
            for extension in importlib.machinery.all_suffixes() + ['/']:
                plugin_zip_module_path = '%s%s' % (plugin_name, extension)
                if plugin_zip_module_path in zf_name_list:
                    LOGGER.debug('Found plugin module: %s', os.path.join(archive, plugin_zip_module_path))
                    break
            else:
                raise PluginError('missing plugin module in %s' % archive)

            # CHECK FOR THE PLUGIN TO BE ALREADY RUNNING
            plugin_id = plugin_spec.get('plugin', 'id')
            plugin_name = plugin_spec.get('plugin', 'name')
            if self.session.plugin(plugin_spec.get('plugin', 'id')):
                raise PluginError('plugin %s (id: %s) is already installed' % (plugin_name, plugin_id))

            # CHECK FOR THE PLUGIN NAMESPACE TO BE UNIQUE
            if plugin_id in self.info:
                raise PluginError('plugin %s (id: %s) is already installed' % (plugin_name, plugin_id))

            # COPY THE PLUGIN
            mkdir('@home/plugins/')
            fcopy(archive, '@home/plugins/')

        except Exception as e:
            LOGGER.error('Failed to install plugin: %s', e, exc_info=not isinstance(e, PluginError))
            raise e
        else:
            return plugin_spec
Example #5
0
def qapp(qapp_args, tmpdir_factory):
    """
    Overrides pytest-qt default qapp fixture to provide
    an instance of Eddy.

    You can use the ``qapp`` fixture in tests which require a ``QApplication``
    to run, but where you don't need full ``qtbot`` functionality.
    """
    app = QtWidgets.QApplication.instance()
    if app is None:
        global _qapp_instance
        os.environ['JAVA_HOME'] = findJavaHome() or ''

        if sys.platform.startswith('win'):
            path = os.getenv('PATH', '')
            path = path.split(os.pathsep)
            path.insert(0, os.path.join(os.environ['JAVA_HOME'], 'jre', 'bin'))
            if platform.architecture()[0] == '32bit':
                path.insert(
                    0,
                    os.path.join(os.environ['JAVA_HOME'], 'jre', 'bin',
                                 'client'))
            else:
                path.insert(
                    0,
                    os.path.join(os.environ['JAVA_HOME'], 'jre', 'bin',
                                 'server'))
            os.environ['PATH'] = os.pathsep.join(path)

        for path in pkg_resources.resource_listdir(eddy.core.jvm.__name__,
                                                   'lib'):
            if File.forPath(path) is File.Jar:
                addJVMClasspath(
                    pkg_resources.resource_filename(eddy.core.jvm.__name__,
                                                    os.path.join('lib', path)))
        # noinspection PyTypeChecker
        addJVMOptions('-ea', '-Xmx512m')

        workspace_tmpdir = tmpdir_factory.mktemp('settings')
        QtCore.QSettings.setPath(QtCore.QSettings.NativeFormat,
                                 QtCore.QSettings.UserScope,
                                 str(workspace_tmpdir))
        settings = QtCore.QSettings(ORGANIZATION, APPNAME)
        settings.setValue('workspace/home', str(workspace_tmpdir))
        settings.setValue('update/check_on_startup', False)

        argparser = getArgumentParser()
        options, args = argparser.parse_known_args(qapp_args)
        _qapp_instance = Eddy(options, args)
        _qapp_instance.configure(options)
        yield _qapp_instance
    else:
        yield app
Example #6
0
    def event(self, event):
        """
        Executed when an event is received.
        :type event: T <= QEvent | QFileOpenEvent
        :rtype: bool
        """
        # HANDLE FILEOPEN EVENT (TRIGGERED BY MACOS WHEN DOUBLE CLICKING A FILE)
        #if event.type() == QtCore.QEvent.FileOpen and not __debug__:
        if event.type() == QtCore.QEvent.FileOpen:
            path = expandPath(event.file())
            #fileName,fileExtension = os.path.splitext(path)
            type = File.forPath(path)
            if type and type is File.Graphol:
                if fexists(path):
                    if self.started:
                        self.sgnCreateSession.emit(path)
                    else:
                        # CACHE PATH UNTIL APPLICATION STARTUP HAS COMPLETED
                        self.openFilePath = path

        return super().event(event)
Example #7
0
    def configure(self, options):
        """
        Perform initial configuration tasks for Eddy to work properly.
        :type options: Namespace
        """
        #############################################
        # DRAW THE SPLASH SCREEN
        #################################

        splash = None
        if not options.nosplash:
            splash = Splash(mtime=4)
            splash.show()

        #############################################
        # CONFIGURE RECENT PROJECTS
        #################################

        settings = QtCore.QSettings(ORGANIZATION, APPNAME)
        examples = [
            expandPath('@examples/Animals'),
            expandPath('@examples/Diet'),
            expandPath('@examples/Family'),
            expandPath('@examples/LUBM'),
            expandPath('@examples/Pizza'),
        ]

        if not settings.contains('project/recent'):
            # From PyQt5 documentation: if the value of the setting is a container (corresponding
            # to either QVariantList, QVariantMap or QVariantHash) then the type is applied to the
            # contents of the container. So we can't use an empty list as default value because
            # PyQt5 needs to know the type of the contents added to the collection: we avoid
            # this problem by placing the list of example projects as recent project list.
            settings.setValue('project/recent', examples)
        else:
            # If we have some projects in our recent list, check whether they exists on the
            # filesystem. If they do not exists we remove them from our recent list.
            projects = []
            for path in map(expandPath, settings.value('project/recent')):
                if isdir(path) and path not in projects:
                    projects.append(path)
            settings.setValue('project/recent', projects or examples)
            settings.sync()

        #############################################
        # CONFIGURE FONTS
        #################################

        fontDB = QtGui.QFontDatabase()
        fontDB.addApplicationFont(':/fonts/Roboto-Black')
        fontDB.addApplicationFont(':/fonts/Roboto-BlackItalic')
        fontDB.addApplicationFont(':/fonts/Roboto-Bold')
        fontDB.addApplicationFont(':/fonts/Roboto-BoldItalic')
        fontDB.addApplicationFont(':/fonts/Roboto-Italic')
        fontDB.addApplicationFont(':/fonts/Roboto-Light')
        fontDB.addApplicationFont(':/fonts/Roboto-LightItalic')
        fontDB.addApplicationFont(':/fonts/Roboto-Medium')
        fontDB.addApplicationFont(':/fonts/Roboto-MediumItalic')
        fontDB.addApplicationFont(':/fonts/Roboto-Regular')
        fontDB.addApplicationFont(':/fonts/Roboto-Thin')
        fontDB.addApplicationFont(':/fonts/Roboto-ThinItalic')
        fontDB.addApplicationFont(':/fonts/RobotoCondensed-Bold')
        fontDB.addApplicationFont(':/fonts/RobotoCondensed-BoldItalic')
        fontDB.addApplicationFont(':/fonts/RobotoCondensed-Italic')
        fontDB.addApplicationFont(':/fonts/RobotoCondensed-Light')
        fontDB.addApplicationFont(':/fonts/RobotoCondensed-LightItalic')
        fontDB.addApplicationFont(':/fonts/RobotoCondensed-Regular')
        fontDB.addApplicationFont(':/fonts/RobotoMono-Bold')
        fontDB.addApplicationFont(':/fonts/RobotoMono-BoldItalic')
        fontDB.addApplicationFont(':/fonts/RobotoMono-Italic')
        fontDB.addApplicationFont(':/fonts/RobotoMono-Light')
        fontDB.addApplicationFont(':/fonts/RobotoMono-LightItalic')
        fontDB.addApplicationFont(':/fonts/RobotoMono-Medium')
        fontDB.addApplicationFont(':/fonts/RobotoMono-MediumItalic')
        fontDB.addApplicationFont(':/fonts/RobotoMono-Regular')
        fontDB.addApplicationFont(':/fonts/RobotoMono-Thin')
        fontDB.addApplicationFont(':/fonts/RobotoMono-ThinItalic')

        self.setFont(Font('Roboto', 12))

        #############################################
        # CONFIGURE LAYOUT
        #################################

        buffer = ''
        resources = expandPath('@resources/styles/')
        for name in os.listdir(resources):
            path = os.path.join(resources, name)
            if fexists(path) and File.forPath(path) is File.Qss:
                buffer += fread(path)
        self.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps)
        self.setStyle(EddyProxyStyle('Fusion'))
        self.setStyleSheet(buffer)

        #############################################
        # LOOKUP PLUGINS
        #################################

        PluginManager.scan('@plugins/', '@home/plugins/')

        #############################################
        # CLOSE THE SPLASH SCREEN
        #################################

        if splash and not options.nosplash:
            splash.sleep()
            splash.close()

        #############################################
        # CONFIGURE THE WORKSPACE
        #################################

        workspace = expandPath(settings.value('workspace/home', WORKSPACE,
                                              str))
        if not isdir(workspace):
            window = WorkspaceDialog()
            if window.exec_() == WorkspaceDialog.Rejected:
                raise SystemExit
Example #8
0
def main():
    """
    Application entry point.
    """
    #############################################
    # SETUP EXCEPTION HOOK
    #################################
    sys.excepthook = base_except_hook

    #############################################
    # PARSE ARGUMENTS AND CREATE THE APPLICATION
    #################################

    # ENABLE HIGH-DPI SUPPORT
    QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
    QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps)
    QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_Use96Dpi)

    global app
    app = Eddy(sys.argv)
    if app.isRunning():
        sys.exit(0)

    #############################################
    # JVM SETUP
    #################################

    JAVA_HOME = findJavaHome()

    if not JAVA_HOME or not os.path.isdir(JAVA_HOME):
        settings = QtCore.QSettings()
        shouldDisplayDialog = settings.value('dialogs/noJVM')
        if not shouldDisplayDialog:
            # CHECKBOX CALLBACK
            def checkboxStateChanged(state):
                settings.setValue('dialogs/noJVM', state == QtCore.Qt.Checked)
                settings.sync()

            chkbox = QtWidgets.QCheckBox("Don't show this warning again.")
            msgbox = QtWidgets.QMessageBox()
            #msgbox.setIconPixmap(QtGui.QPixmap(':/images/eddy-sad'))
            msgbox.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))
            msgbox.setWindowTitle('Missing Java Runtime Environment')
            msgbox.setText('Unable to locate a valid Java installation on your system.')
            msgbox.setInformativeText('<p>Some features in {0} require access to a <br/>'
                                      '<a href="{1}">Java Runtime Environment</a> '
                                      'and will not be available if you continue.</p>'
                                      '<p>You can download a copy of the Java Runtime Environment '
                                      'from the <a href={2}>Java Downloads</a> page.</p>'
                                      .format(APPNAME, 'https://www.java.com/download',
                                              'https://www.oracle.com/technetwork/java/javase/downloads/index.html'))
            msgbox.setStandardButtons(QtWidgets.QMessageBox.Abort | QtWidgets.QMessageBox.Ok)
            msgbox.setDefaultButton(QtWidgets.QMessageBox.Abort)
            msgbox.setCheckBox(chkbox)
            buttonOk = msgbox.button(QtWidgets.QMessageBox.Ok)
            buttonOk.setText('Continue without JRE')
            buttonQuit = msgbox.button(QtWidgets.QMessageBox.Abort)
            buttonQuit.setText('Quit {0}'.format(APPNAME))
            # noinspection PyArgumentList
            buttonQuit.clicked.connect(app.doQuit, QtCore.Qt.QueuedConnection)
            connect(chkbox.stateChanged, checkboxStateChanged)
            ret = msgbox.exec_()
            if ret == QtWidgets.QMessageBox.Abort:
                return 1

    #############################################
    # BEGIN ENVIRONMENT SPECIFIC SETUP
    #################################

    os.environ['JAVA_HOME'] = JAVA_HOME or ''

    # ADD THE DIRECTORY CONTAINING JVM.DLL TO THE PATH VARIABLE ON WINDOWS
    if IS_WIN:
        path = os.getenv('PATH', '')
        path = path.split(os.pathsep)
        # FOR JAVA 8
        if isdir(os.path.join(os.environ['JAVA_HOME'], 'jre', 'bin')):
            bindir = os.path.join(os.environ['JAVA_HOME'], 'jre', 'bin')
        # FOR JAVA 9+
        else:
            bindir = os.path.join(os.environ['JAVA_HOME'], 'bin')
        path.insert(0, bindir)
        if platform.architecture()[0] == '32bit':
            path.insert(0, os.path.join(bindir, 'client'))
        else:
            path.insert(0, os.path.join(bindir, 'server'))
        os.environ['PATH'] = os.pathsep.join(path)

    # SET CLASSPATH AND OPTIONS
    if IS_FROZEN:
        resources = expandPath('@resources/lib/')
        if isdir(resources):
            for name in os.listdir(resources):
                path = os.path.join(resources, name)
                if os.path.isfile(path):
                    addJVMClasspath(path)
    else:
        from pkg_resources import resource_filename, resource_listdir
        for path in resource_listdir(eddy.core.jvm.__name__, 'lib'):
            if File.forPath(path) is File.Jar:
                addJVMClasspath(resource_filename(eddy.core.jvm.__name__,
                                                  os.path.join('lib', path)))
    addJVMOptions('-Xmx512m', '-XX:+DisableExplicitGC')

    #############################################
    # START THE APPLICATION
    #################################

    LOGGER.separator(separator='-')
    LOGGER.frame('%s v%s', APPNAME, VERSION, separator='|')
    LOGGER.frame(COPYRIGHT, separator='|')
    LOGGER.separator(separator='-')
    LOGGER.frame('OS: %s %s', platform.system(), platform.release(), separator='|')
    LOGGER.frame('Python version: %s', platform.python_version(), separator='|')
    LOGGER.frame('Qt version: %s', QtCore.QT_VERSION_STR, separator='|')
    LOGGER.frame('PyQt version: %s', QtCore.PYQT_VERSION_STR, separator='|')
    LOGGER.frame('SIP version: %s', sip.SIP_VERSION_STR, separator='|')
    LOGGER.separator(separator='-')

    app.configure()
    app.start()
    ret = app.exec_()
    if ret == Eddy.RestartCode:
        nargs = []
        if os.path.basename(sys.argv[0]) == 'eddy':
            # LAUNCHED VIA LAUNCHER SCRIPT
            nargs.append(sys.argv[0])
        elif IS_FROZEN:
            # LAUNCHED FROM DISTRIBUTION EXECUTABLE
            nargs.append(sys.executable)
        else:
            # LAUNCHED VIA THE INTERPRETER
            nargs.extend([sys.executable, sys.argv[0]])
        nargs.extend(sys.argv[1:])
        subprocess.Popen(nargs)
    sys.exit(ret)
Example #9
0
    def install(self, archive):
        """
        Install the given reasoner archive.
        During the installation process we'll check for a correct reasoner structure,
        i.e. for the .spec file and the reasoner module to be available. We won't check if
        the reasoner actually runs since this will be handle by the application statt sequence.
        :type archive: str
        :rtype: ReasonerSpec
        """
        try:

            ## CHECK FOR CORRECT REASONER ARCHIVE
            if not fexists(archive):
                raise ReasonerError('file not found: %s' % archive)
            if not File.forPath(archive) is File.Zip:
                raise ReasonerError('%s is not a valid reasoner' % archive)

            ## LOOKUP THE SPEC FILE
            zf = ZipFile(archive)
            zf_name_list = zf.namelist()
            for file_or_directory in zf_name_list:
                if file_or_directory.endswith('reasoner.spec'):
                    LOGGER.debug('Found reasoner .spec: %s', os.path.join(archive, file_or_directory))
                    reasoner_spec_content = zf.read(file_or_directory).decode('utf8')
                    reasoner_spec = self.spec(reasoner_spec_content)
                    break
            else:
                raise ReasonerError('missing reasoner.spec in %s' % archive)

            ## LOOKUP THE REASONER MODULE
            reasoner_name = reasoner_spec.get('reasoner', 'id')
            reasoner_zip_base_path = rstrip(file_or_directory, 'reasoner.spec')
            reasoner_zip_module_base_path = os.path.join(reasoner_zip_base_path, reasoner_name)
            for extension in ('.pyc', '.pyo', '.py'):
                reasoner_zip_module_path = '%s%s' % (reasoner_zip_module_base_path, extension)
                if reasoner_zip_module_path in zf_name_list:
                    LOGGER.debug('Found reasoner module: %s', os.path.join(archive, reasoner_zip_module_path))
                    break
            else:
                raise ReasonerError('missing reasoner module: %s.py(c|o) in %s' % (reasoner_zip_module_base_path, archive))

            # CHECK FOR THE REASONER TO BE ALREADY RUNNING
            reasoner_id = reasoner_spec.get('reasoner', 'id')
            reasoner_name = reasoner_spec.get('reasoner', 'name')
            if self.session.reasoner(reasoner_spec.get('reasoner', 'id')):
                raise ReasonerError('reasoner %s (id: %s) is already installed' % (reasoner_name, reasoner_id))

            # CHECK FOR THE REASONER NAMESPACE TO BE UNIQUE
            reasoner_module_base_path = rstrip(first(filter(None, reasoner_zip_module_path.split(os.path.sep))), File.Zip.extension)
            for path in (expandPath('@reasoners/'), expandPath('@home/reasoners/')):
                for entry in os.listdir(path):
                    if reasoner_module_base_path == rstrip(entry, File.Zip.extension):
                        raise ReasonerError('reasoner %s (id: %s) is already installed' % (reasoner_name, reasoner_id))

            # COPY THE REASONER
            mkdir('@home/reasoners/')
            fcopy(archive, '@home/reasoners/')

        except Exception as e:
            LOGGER.error('Failed to install reasoner: %s', e, exc_info=not isinstance(e, ReasonerError))
            raise e
        else:
            return reasoner_spec
Example #10
0
    def configure(self, options):
        """
        Perform initial configuration tasks for Eddy to work properly.
        :type options: Namespace
        """
        #############################################
        # DRAW THE SPLASH SCREEN
        #################################

        splash = None
        if not options.nosplash:
            splash = Splash(mtime=4)
            splash.show()

        #############################################
        # CONFIGURE RECENT PROJECTS
        #################################

        settings = QtCore.QSettings(ORGANIZATION, APPNAME)
        examples = [
            expandPath('@examples/Animals'),
            expandPath('@examples/Diet'),
            expandPath('@examples/Family'),
            expandPath('@examples/LUBM'),
            expandPath('@examples/Pizza'),
        ]

        if not settings.contains('project/recent'):
            # From PyQt5 documentation: if the value of the setting is a container (corresponding
            # to either QVariantList, QVariantMap or QVariantHash) then the type is applied to the
            # contents of the container. So we can't use an empty list as default value because
            # PyQt5 needs to know the type of the contents added to the collection: we avoid
            # this problem by placing the list of example projects as recent project list.
            settings.setValue('project/recent', examples)
        else:
            # If we have some projects in our recent list, check whether they exists on the
            # filesystem. If they do not exists we remove them from our recent list.
            projects = []
            for path in map(expandPath, settings.value('project/recent')):
                if isdir(path) and path not in projects:
                    projects.append(path)
            settings.setValue('project/recent', projects or examples)
            settings.sync()

        #############################################
        # CONFIGURE FONTS
        #################################

        fontDB = QtGui.QFontDatabase()
        fontDB.addApplicationFont(':/fonts/Roboto-Black')
        fontDB.addApplicationFont(':/fonts/Roboto-BlackItalic')
        fontDB.addApplicationFont(':/fonts/Roboto-Bold')
        fontDB.addApplicationFont(':/fonts/Roboto-BoldItalic')
        fontDB.addApplicationFont(':/fonts/Roboto-Italic')
        fontDB.addApplicationFont(':/fonts/Roboto-Light')
        fontDB.addApplicationFont(':/fonts/Roboto-LightItalic')
        fontDB.addApplicationFont(':/fonts/Roboto-Medium')
        fontDB.addApplicationFont(':/fonts/Roboto-MediumItalic')
        fontDB.addApplicationFont(':/fonts/Roboto-Regular')
        fontDB.addApplicationFont(':/fonts/Roboto-Thin')
        fontDB.addApplicationFont(':/fonts/Roboto-ThinItalic')
        fontDB.addApplicationFont(':/fonts/RobotoCondensed-Bold')
        fontDB.addApplicationFont(':/fonts/RobotoCondensed-BoldItalic')
        fontDB.addApplicationFont(':/fonts/RobotoCondensed-Italic')
        fontDB.addApplicationFont(':/fonts/RobotoCondensed-Light')
        fontDB.addApplicationFont(':/fonts/RobotoCondensed-LightItalic')
        fontDB.addApplicationFont(':/fonts/RobotoCondensed-Regular')
        fontDB.addApplicationFont(':/fonts/RobotoMono-Bold')
        fontDB.addApplicationFont(':/fonts/RobotoMono-BoldItalic')
        fontDB.addApplicationFont(':/fonts/RobotoMono-Italic')
        fontDB.addApplicationFont(':/fonts/RobotoMono-Light')
        fontDB.addApplicationFont(':/fonts/RobotoMono-LightItalic')
        fontDB.addApplicationFont(':/fonts/RobotoMono-Medium')
        fontDB.addApplicationFont(':/fonts/RobotoMono-MediumItalic')
        fontDB.addApplicationFont(':/fonts/RobotoMono-Regular')
        fontDB.addApplicationFont(':/fonts/RobotoMono-Thin')
        fontDB.addApplicationFont(':/fonts/RobotoMono-ThinItalic')

        self.setFont(Font('Roboto', 12))

        #############################################
        # CONFIGURE LAYOUT
        #################################

        buffer = ''
        resources = expandPath('@resources/styles/')
        for name in os.listdir(resources):
            path = os.path.join(resources, name)
            if fexists(path) and File.forPath(path) is File.Qss:
                buffer += fread(path)
        self.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps)
        self.setStyle(EddyProxyStyle('Fusion'))
        self.setStyleSheet(buffer)

        #############################################
        # CLOSE THE SPLASH SCREEN
        #################################

        if splash and not options.nosplash:
            splash.sleep()
            splash.close()

        #############################################
        # CONFIGURE THE WORKSPACE
        #################################

        workspace = expandPath(settings.value('workspace/home', WORKSPACE, str))
        if not isdir(workspace):
            window = WorkspaceDialog()
            if window.exec_() == WorkspaceDialog.Rejected:
                raise SystemExit
Example #11
0
    def install(self, archive):
        """
        Install the given plugin archive.
        During the installation process we'll check for a correct plugin structure,
        i.e. for the .spec file and the plugin module to be available. We won't check if
        the plugin actually runs since this will be handle by the application statt sequence.
        :type archive: str
        :rtype: PluginSpec
        """
        try:

            ## CHECK FOR CORRECT PLUGIN ARCHIVE
            if not fexists(archive):
                raise PluginError('file not found: %s' % archive)
            if not File.forPath(archive) is File.Zip:
                raise PluginError('%s is not a valid plugin' % archive)

            ## LOOKUP THE SPEC FILE
            zf = ZipFile(archive)
            zf_name_list = zf.namelist()
            for file_or_directory in zf_name_list:
                if file_or_directory.endswith('plugin.spec'):
                    LOGGER.debug('Found plugin .spec: %s', os.path.join(archive, file_or_directory))
                    plugin_spec_content = zf.read(file_or_directory).decode('utf8')
                    plugin_spec = self.spec(plugin_spec_content)
                    break
            else:
                raise PluginError('missing plugin.spec in %s' % archive)

            ## LOOKUP THE PLUGIN MODULE
            plugin_name = plugin_spec.get('plugin', 'id')
            plugin_zip_base_path = rstrip(file_or_directory, 'plugin.spec')
            plugin_zip_module_base_path = os.path.join(plugin_zip_base_path, plugin_name)
            for extension in ('.pyc', '.pyo', '.py'):
                plugin_zip_module_path = '%s%s' % (plugin_zip_module_base_path, extension)
                if plugin_zip_module_path in zf_name_list:
                    LOGGER.debug('Found plugin module: %s', os.path.join(archive, plugin_zip_module_path))
                    break
            else:
                raise PluginError('missing plugin module: %s.py(c|o) in %s' % (plugin_zip_module_base_path, archive))

            # CHECK FOR THE PLUGIN TO BE ALREADY RUNNING
            plugin_id = plugin_spec.get('plugin', 'id')
            plugin_name = plugin_spec.get('plugin', 'name')
            if self.session.plugin(plugin_spec.get('plugin', 'id')):
                raise PluginError('plugin %s (id: %s) is already installed' % (plugin_name, plugin_id))

            # CHECK FOR THE PLUGIN NAMESPACE TO BE UNIQUE
            plugin_module_base_path = rstrip(first(filter(None, plugin_zip_module_path.split(os.path.sep))), File.Zip.extension)
            for path in (expandPath('@plugins/'), expandPath('@home/plugins/')):
                for entry in os.listdir(path):
                    if plugin_module_base_path == rstrip(entry, File.Zip.extension):
                        raise PluginError('plugin %s (id: %s) is already installed' % (plugin_name, plugin_id))

            # COPY THE PLUGIN
            mkdir('@home/plugins/')
            fcopy(archive, '@home/plugins/')

        except Exception as e:
            LOGGER.error('Failed to install plugin: %s', e, exc_info=not isinstance(e, PluginError))
            raise e
        else:
            return plugin_spec