Exemple #1
0
 def import_reasoner_from_directory(cls, directory):
     """
     Import a reasoner from the given directory:
     * 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 directory: str
     :rtype: tuple
     """
     if isdir(directory):
         reasoner_spec_path = os.path.join(directory, 'reasoner.spec')
         if fexists(reasoner_spec_path):
             try:
                 #LOGGER.debug('Found reasoner .spec: %s', reasoner_spec_path)
                 reasoner_spec = ReasonerManager.spec(fread(reasoner_spec_path))
                 reasoner_name = reasoner_spec.get('reasoner', 'id')
                 for extension in ('.pyc', '.pyo', '.py'):
                     reasoner_path = os.path.join(directory, '%s%s' % (reasoner_name, extension))
                     if fexists(reasoner_path):
                         #LOGGER.debug('Found reasoner module: %s', reasoner_path)
                         reasoner_module = SourceFileLoader(reasoner_name, reasoner_path).load_module()
                         reasoner_class = ReasonerManager.find_class(reasoner_module, reasoner_name)
                         return reasoner_spec, reasoner_class
                 else:
                     raise ReasonerError('missing reasoner module: %s.py(c|o)' % os.path.join(directory, reasoner_name))
             except Exception as e:
                 LOGGER.exception('Failed to import reasoner: %s', e)
Exemple #2
0
 def import_plugin_from_directory(cls, directory):
     """
     Import a plugin from the given directory:
     * 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 directory: str
     :rtype: tuple
     """
     if isdir(directory):
         plugin_spec_path = os.path.join(directory, 'plugin.spec')
         if fexists(plugin_spec_path):
             try:
                 #LOGGER.debug('Found plugin .spec: %s', plugin_spec_path)
                 plugin_spec = PluginManager.spec(fread(plugin_spec_path))
                 plugin_name = plugin_spec.get('plugin', 'id')
                 for extension in ('.pyc', '.pyo', '.py'):
                     plugin_path = os.path.join(directory, '%s%s' % (plugin_name, extension))
                     if fexists(plugin_path):
                         #LOGGER.debug('Found plugin module: %s', plugin_path)
                         plugin_module = SourceFileLoader(plugin_name, plugin_path).load_module()
                         plugin_class = PluginManager.find_class(plugin_module, plugin_name)
                         return plugin_spec, plugin_class
                 else:
                     raise PluginError('missing plugin module: %s.py(c|o)' % os.path.join(directory, plugin_name))
             except Exception as e:
                 LOGGER.exception('Failed to import plugin: %s', e)
Exemple #3
0
 def import_plugin_from_directory(self, directory):
     """
     Import a plugin from the given directory:
     * 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 directory: str
     :rtype: tuple
     """
     if isdir(directory):
         plugin_spec_path = os.path.join(directory, 'plugin.spec')
         if fexists(plugin_spec_path):
             try:
                 LOGGER.debug('Found plugin .spec: %s', plugin_spec_path)
                 plugin_spec = self.spec(fread(plugin_spec_path))
                 plugin_name = plugin_spec.get('plugin', 'id')
                 for extension in ('.pyc', '.pyo', '.py'):
                     plugin_path = os.path.join(directory, '%s%s' % (plugin_name, extension))
                     if fexists(plugin_path):
                         LOGGER.debug('Found plugin module: %s', plugin_path)
                         plugin_module = SourceFileLoader(plugin_name, plugin_path).load_module()
                         plugin_class = self.find_class(plugin_module, plugin_name)
                         return plugin_spec, plugin_class
                 else:
                     raise PluginError('missing plugin module: %s.py(c|o)' % os.path.join(directory, plugin_name))
             except Exception as e:
                 LOGGER.exception('Failed to import plugin: %s', e)
Exemple #4
0
        def buildDmg(self):
            """Build the DMG image."""
            try:
                import dmgbuild
            except ImportError:
                raise OSError(
                    'Unable to import dmgbuild: please install the dmgbuild package.'
                )

            if fexists(self.dmgName):
                os.unlink(self.dmgName)

            defines = {
                'appname': APPNAME,
                'files': [self.bundleDir],
                'license_file': expandPath('@root/LICENSE'),
                'icon_locations': {
                    '{}.app'.format(APPNAME): (60, 50)
                },
            }

            if self.applications_shortcut:
                defines['symlinks'] = {'Applications': '/Applications'}
                defines['icon_locations']['Applications'] = (60, 130)

            if self.volume_background:
                if not fexists(self.volume_background):
                    raise OSError(
                        'DMG volume background image not found at {0}'.format(
                            self.volume_background))
                print('Using DMG volume background: {0}'.format(
                    self.volume_background))
                from PIL import Image
                w, h = Image.open(self.volume_background).size
                defines['background'] = self.volume_background
                defines['window_rect'] = ((100, 500), (str(w), (str(h))))

            if self.volume_icon:
                if not fexists(self.volume_icon):
                    raise OSError('DMG volume icon not found at {0}'.format(
                        self.volume_icon))
                print('Using DMG volume icon: {0}'.format(self.volume_icon))
                defines['icon'] = self.volume_icon

            # Create the disk image using dmgbuild package.
            dmgbuild.build_dmg(
                self.dmgName,
                self.volume_label,
                settings_file=expandPath('@support/dmgbuild/settings.py'),
                defines=defines,
            )
Exemple #5
0
        def buildDMG(self):
            """
            Build the DMG image.
            """
            if not isdir('@support/createdmg') or not fexists('@support/createdmg/create-dmg'):
                raise OSError('unable to find create-dmg utility: please clone Eddy with all its submodules' )

            if fexists(self.dmgName):
                os.unlink(self.dmgName)

            stagingDir = os.path.join(self.buildDir, 'tmp')
            if isdir(stagingDir):
                rmdir(stagingDir)

            self.mkpath(stagingDir)

            # Move the app bundle into a separate folder that will be used as source folder for the DMG image
            if subprocess.call(['cp', '-R', self.bundleDir, stagingDir]) != 0:
                raise OSError('could not move app bundle in staging directory')

            # We create the DMG disk image using the create-dmg submodule.
            params = [expandPath('@support/createdmg/create-dmg')]
            params.extend(['--volname', self.volume_label])
            params.extend(['--text-size', '12'])
            params.extend(['--icon-size', '48'])
            params.extend(['--icon', '{0}.app'.format(self.bundleName), '60', '50'])
            params.extend(['--hide-extension', '{0}.app'.format(self.bundleName)])

            if self.applications_shortcut:
                params.extend(['--app-drop-link', '60', '130'])

            if self.volume_background:
                if not fexists(self.volume_background):
                    raise OSError('DMG volume background image not found at {0}'.format(self.volume_background))
                print('Using DMG volume background: {0}'.format(self.volume_background))
                from PIL import Image
                w, h = Image.open(self.volume_background).size
                params.extend(['--background', self.volume_background, '--window-size', str(w), str(h)])

            if self.volume_icon:
                if not fexists(self.volume_icon):
                    raise OSError('DMG volume icon not found at {0}'.format(self.volume_icon))
                print('Using DMG volume icon: {0}'.format(self.volume_icon))
                params.extend(['--volicon', self.volume_icon])

            params.extend([self.dmgName, stagingDir])

            subprocess.call(params)
            rmdir(stagingDir)
Exemple #6
0
 def doUpdateRecentProjects(self):
     """
     Update the list of recent projects.
     """
     # UPDATE THE RECENT PROJECT LIST
     recentList = []
     settings = QtCore.QSettings()
     for path in map(expandPath,
                     settings.value('project/recent', None, str) or []):
         if fexists(path):
             recentList.append(path)
     settings.setValue('project/recent', recentList)
     settings.sync()
     # CLEAR CURRENT LAYOUT
     for i in reversed(range(self.innerLayoutL.count())):
         item = self.innerLayoutL.itemAt(i)
         self.innerLayoutL.removeItem(item)
     # DISPOSE NEW PROJECT BLOCK
     if recentList:
         self.placeholder.setVisible(False)
         for path in recentList:
             project = ProjectBlock(path, self.innerWidgetL)
             connect(project.sgnDeleteProject, self.doDeleteProject)
             connect(project.sgnOpenProject, self.doOpenProject)
             connect(project.sgnRemoveProject, self.doRemoveProject)
             self.innerLayoutL.addWidget(project, 0, QtCore.Qt.AlignTop)
     else:
         self.placeholder.setVisible(True)
Exemple #7
0
 def do_import(self):
     """
     Import an ontology into the currently active Project.
     """
     self.debug('Open dialog')
     dialog = QtWidgets.QFileDialog(self.session)
     dialog.setAcceptMode(QtWidgets.QFileDialog.AcceptOpen)
     dialog.setDirectory(expandPath('~'))
     dialog.setFileMode(QtWidgets.QFileDialog.ExistingFiles)
     dialog.setViewMode(QtWidgets.QFileDialog.Detail)
     if dialog.exec_():
         selected = [x for x in dialog.selectedFiles() if fexists(x)]
         if selected:
             try:
                 with BusyProgressDialog(parent=self.session) as progress:
                     for path in selected:
                         progress.setWindowTitle('Importing {0}...'.format(
                             os.path.basename(path)))
                         worker = DescriptionsLoader(
                             path, self.session.project, self.session)
                         worker.run()
             except Exception as e:
                 msgbox = QtWidgets.QMessageBox(self.session)
                 msgbox.setDetailedText(format_exception(e))
                 msgbox.setIconPixmap(
                     QtGui.QIcon(
                         ':/icons/48/ic_error_outline_black').pixmap(48))
                 msgbox.setStandardButtons(QtWidgets.QMessageBox.Close)
                 msgbox.setText(
                     'Eddy could not import all the selected files!')
                 msgbox.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy'))
                 msgbox.setWindowTitle('Import failed!')
                 msgbox.exec_()
Exemple #8
0
    def find_spec(cls, file_or_directory):
        """
        Searches the given file or directory for a 'plugin.spec' file and tries to load it,
        or returns 'None' if no such file exists.

        :type file_or_directory: str
        :rtype: PluginSpec
        """
        file_or_directory = expandPath(file_or_directory)
        try:
            if os.path.exists(file_or_directory) and os.access(
                    file_or_directory, os.R_OK):
                # READ SPEC FILE FROM DIRECTORY
                if isdir(file_or_directory):
                    plugin_spec_path = os.path.join(file_or_directory,
                                                    'plugin.spec')
                    if fexists(plugin_spec_path):
                        return cls.spec(fread(plugin_spec_path))
                # READ SPEC FILE FROM ZIP ARCHIVE
                elif is_zipfile(file_or_directory):
                    zf = ZipFile(file_or_directory)
                    zf_name_list = zf.namelist()
                    if 'plugin.spec' in zf_name_list:
                        plugin_spec_content = zf.read('plugin.spec').decode(
                            'utf8')
                        return cls.spec(plugin_spec_content)
        except Exception as e:
            LOGGER.exception('Failed to load plugin spec: %s', e)
Exemple #9
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)
Exemple #10
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)
Exemple #11
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)
Exemple #12
0
    def make_installer(self):
        """
        Create a Windows installer using InnoSetup
        """
        if WIN32:

            import yaml
            with open(os.path.join('support', 'innosetup', 'build.yaml'), 'r') as f:
                config = yaml.load(f)
            if 'scripts' not in config:
                print("ERROR: invalid config file: could not find 'scripts' section")
                sys.exit(1)
            if not len(config['scripts']):
                print("ERROR: invalid config file: no entry found in 'scripts' section")
                sys.exit(1)
            if 'iscc' not in config:
                print("ERROR: invalid config file: could not find 'iscc' entry")
                sys.exit(1)
            if not fexists(os.path.join('support', 'innosetup', config['iscc'])):
                print("ERROR: invalid config file: '{0}' is not a file".format(config['iscc']))
                sys.exit(1)

            # Location of the InnoSetup Compiler program taken from environment.
            config['iscc'] = os.environ.get('ISCC_EXE', config['iscc'])
            if not config['iscc'].lower().endswith('iscc.exe'):
                print("ERROR: invalid location for the ISCC.exe program: {0}".format(config['iscc']))
                sys.exit(1)

            # Build each given innosetup script
            for filename in config['scripts']:

                script_file = os.path.join('support', 'innosetup', filename)
                distutils.log.info("building: {0}".format(script_file))

                try:
                    cmd = [
                        config['iscc'],
                        script_file,
                        '/Q',
                        '/O{0}'.format(DIST_DIR),
                        '/dEDDY_APPID={0}'.format(APPID),
                        '/dEDDY_APPNAME={0}'.format(APPNAME),
                        '/dEDDY_ARCHITECTURE={0}'.format(platform.machine().lower()),
                        '/dEDDY_BUGTRACKER={0}'.format(BUG_TRACKER),
                        '/dEDDY_BUILD_PATH={0}'.format(self.build_exe),
                        '/dEDDY_COPYRIGHT={0}'.format(COPYRIGHT),
                        '/dEDDY_DOWNLOAD_URL={0}'.format(GRAPHOL_HOME),
                        '/dEDDY_EXECUTABLE={0}'.format(EXEC_NAME),
                        '/dEDDY_GRAPHOL_URL={0}'.format(GRAPHOL_HOME),
                        '/dEDDY_LICENSE={0}'.format(LICENSE.lower()),
                        '/dEDDY_ORGANIZATION={0}'.format(ORGANIZATION),
                        '/dEDDY_ORGANIZATION_URL={0}'.format(DIAG_HOME),
                        '/dEDDY_PROJECT_HOME={0}'.format(PROJECT_HOME),
                        '/dEDDY_VERSION={0}'.format(VERSION),
                    ]
                    subprocess.call(cmd)
                except Exception as e:
                    distutils.log.error('Failed to build {0}: {1}'.format(script_file, e))
Exemple #13
0
        def setRelativeReferencePaths(self):
            """
            For all files in Contents/MacOS, check if they are binaries with references to other files in that dir.
            If so, make those references relative. The appropriate commands are applied to all files; they will just
            fail for files on which they do not apply.
            """
            files = []
            for root, dirs, dir_files in os.walk(self.binDir):
                files.extend([
                    os.path.join(root, f).replace(self.binDir + '/', '')
                    for f in dir_files
                ])

            for filename in files:
                if filename.endswith('.zip'):
                    continue
                filepath = os.path.join(self.binDir, filename)
                mode = os.stat(filepath).st_mode
                if not mode & stat.S_IWUSR:
                    os.chmod(filepath, mode | stat.S_IWUSR)

                subprocess.call(
                    ('install_name_tool', '-id',
                     '@executable_path/{0}'.format(filename), filepath))
                otool = subprocess.Popen(('otool', '-L', filepath),
                                         stdout=subprocess.PIPE)
                references = otool.stdout.readlines()[1:]

                for reference in references:
                    referenced_file = reference.decode().strip().split()[0]
                    if referenced_file.startswith('@executable_path/'):
                        continue
                    path, name = os.path.split(referenced_file)
                    # Some referenced files have not previously been copied to the executable directory - the
                    # assumption is that you don't need to copy anything from /usr or /System, just from folders
                    # like /opt this fix should probably be elsewhere though.
                    if name not in files and not path.startswith(
                            '/usr') and not path.startswith('/System'):
                        if fexists(referenced_file):
                            self.copy_file(referenced_file,
                                           os.path.join(self.binDir, name))
                            files.append(name)

                    new_reference = None
                    if name in files:
                        new_reference = '@executable_path/{0}'.format(name)
                    elif path.startswith('@rpath'):
                        for i in files:
                            if i.endswith(name):
                                new_reference = '@executable_path/{0}'.format(
                                    i)

                    if new_reference:
                        subprocess.call(
                            ('install_name_tool', '-change', referenced_file,
                             new_reference, filepath))
Exemple #14
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
Exemple #15
0
 def run(self):
     """Command execution."""
     self.appImageName = '{}-{}-{}.AppImage'.format(
         APPNAME, VERSION, EXEC_ARCH)
     self.mkpath(self.dist_dir)
     self.execute(self.build_appimage, (), msg='Creating AppImage...')
     if fexists(self.appImageName):
         self.move_file(
             self.appImageName,
             os.path.join(self.dist_dir, DIST_NAME + '.AppImage'))
Exemple #16
0
 def uninstall(self, plugin):
     """
     Uninstall the given plugin.
     :type plugin: AbstractPlugin
     """
     if self.dispose(plugin):
         self.session.removePlugin(plugin)
         path = plugin.path()
         if isdir(path):
             rmdir(path)
         elif fexists(path):
             fremove(path)
Exemple #17
0
 def uninstall(self, plugin):
     """
     Uninstall the given plugin.
     :type plugin: AbstractPlugin
     """
     if self.dispose(plugin):
         self.session.removePlugin(plugin)
         path = plugin.path()
         if isdir(path):
             rmdir(path)
         elif fexists(path):
             fremove(path)
Exemple #18
0
 def uninstall(self, reasoner):
     """
     Uninstall the given reasoner.
     :type reasoner: AbstractReasoner
     """
     if self.dispose(reasoner):
         self.session.removeReasoner(reasoner)
         path = reasoner.path()
         if isdir(path):
             rmdir(path)
         elif fexists(path):
             fremove(path)
Exemple #19
0
    def createDomDocument(self):
        """
        Create the QDomDocument from where to parse information.
        """
        QtWidgets.QApplication.processEvents()

        LOGGER.info('Loading diagram: %s', self.path)

        if not fexists(self.path):
            raise DiagramNotFoundError('diagram not found: {0}'.format(self.path))

        self.document = QtXml.QDomDocument()
        if not self.document.setContent(fread(self.path)):
            raise DiagramNotValidError('could not parse diagram from {0}'.format(self.path))
Exemple #20
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:
            path = expandPath(event.file())
            if fexists(path):
                if self.started:
                    self.sgnCreateSession.emit(os.path.dirname(path))
                else:
                    # CACHE PATH UNTIL APPLICATION STARTUP HAS COMPLETED
                    self.openFilePath = path

        return super().event(event)
Exemple #21
0
        def setRelativeReferencePaths(self):
            """
            For all files in Contents/MacOS, check if they are binaries with references to other files in that dir.
            If so, make those references relative. The appropriate commands are applied to all files; they will just
            fail for files on which they do not apply.
            """
            files = []
            for root, dirs, dir_files in os.walk(self.binDir):
                files.extend([os.path.join(root, f).replace(self.binDir + '/', '') for f in dir_files])

            for filename in files:
                if filename.endswith('.zip'):
                    continue
                filepath = os.path.join(self.binDir, filename)
                mode = os.stat(filepath).st_mode
                if not mode & stat.S_IWUSR:
                    os.chmod(filepath, mode | stat.S_IWUSR)

                subprocess.call(('install_name_tool', '-id', '@executable_path/{0}'.format(filename), filepath))
                otool = subprocess.Popen(('otool', '-L', filepath), stdout=subprocess.PIPE)
                references = otool.stdout.readlines()[1:]

                for reference in references:
                    referenced_file = reference.decode().strip().split()[0]
                    if referenced_file.startswith('@executable_path/'):
                        continue
                    path, name = os.path.split(referenced_file)
                    # Some referenced files have not previously been copied to the executable directory - the
                    # assumption is that you don't need to copy anything from /usr or /System, just from folders
                    # like /opt this fix should probably be elsewhere though.
                    if name not in files and not path.startswith('/usr') and not path.startswith('/System'):
                        if fexists(referenced_file):
                            self.copy_file(referenced_file, os.path.join(self.binDir, name))
                            files.append(name)

                    new_reference = None
                    if name in files:
                        new_reference = '@executable_path/{0}'.format(name)
                    elif path.startswith('@rpath'):
                        for i in files:
                            if i.endswith(name):
                                new_reference = '@executable_path/{0}'.format(i)

                    if new_reference:
                        subprocess.call(('install_name_tool', '-change', referenced_file, new_reference, filepath))
Exemple #22
0
    def start(self):
        """
        Run the application by showing the welcome dialog.
        """
        # CONFIGURE THE WORKSPACE
        #settings = QtCore.QSettings()
        #workspace = expandPath(settings.value('workspace/home', WORKSPACE, str))
        '''
        if not isdir(workspace):
            window = WorkspaceDialog()
            if window.exec_() == WorkspaceDialog.Rejected:
                raise SystemExit
        '''

        # PROCESS COMMAND LINE ARGUMENTS
        args = self.options.positionalArguments()

        if self.openFilePath:
            args.append(self.openFilePath)
            self.openFilePath = None
        # SHOW WELCOME DIALOG
        self.welcome = Welcome(self)
        self.welcome.show()
        # PROCESS ADDITIONAL COMMAND LINE OPTIONS
        if self.options.isSet(CommandLineParser.OPEN):
            value = self.options.value(CommandLineParser.OPEN)
            if value:
                project = os.path.join(workspace, value)
                if project and isdir(os.path.join(workspace, project)):
                    self.sgnCreateSession.emit(project)
                else:
                    LOGGER.warning('Unable to open project: %s', project)
        # POSITIONAL ARGUMENTS
        elif args:
            fname = expandPath(args[0])
            if fexists(fname):
                #project = os.path.dirname(fname)
                project = fname
                self.sgnCreateSession.emit(project)
            else:
                LOGGER.warning('Unable to open file: %s', fname)
        # COMPLETE STARTUP
        self.started = True
Exemple #23
0
 def createProjectFile(self):
     """
     Serialize a previously created QDomDocument to disk.
     """
     try:
         currPath = self.exportPath if self.exportPath else self.project.path
         if not fexists(currPath):
             folderPath = os.path.dirname(currPath)
             if not isdir(folderPath):
                 mkdir(folderPath)
             fd = os.open(currPath, os.O_CREAT)
             os.close(fd)
         #TODO filename = postfix(self.project.name, File.Graphol.extension)
         #TODO filepath = os.path.join(self.project.path, filename)
         #TODO fwrite(self.document.toString(2), filepath)
         fwrite(self.document.toString(2), currPath)
     except Exception as e:
         raise e
     else:
         LOGGER.info('Saved project %s to %s', self.project.name, currPath)
Exemple #24
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)
Exemple #25
0
 def assertFileExists(self, filepath, msg=None):
     """Assert for the given path to represent a file"""
     if not fexists(filepath):
         standardMsg = '%s is not a file' % safe_repr(expandPath(filepath))
         self.fail(self._formatMessage(msg, standardMsg))
Exemple #26
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
Exemple #27
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
Exemple #28
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
Exemple #29
0
    def configure(self):
        """
        Perform initial configuration tasks for Eddy to work properly.
        """
        #############################################
        # CONFIGURE FONTS
        #################################

        fontDB = QtGui.QFontDatabase()
        fonts = QtCore.QDirIterator(':/fonts/')
        while fonts.hasNext():
            fontDB.addApplicationFont(fonts.next())

        # FONT SUBSTITUTIONS
        QtGui.QFont.insertSubstitution('Sans Serif', 'Roboto')
        QtGui.QFont.insertSubstitution('Monospace', 'Roboto Mono')

        # APPLICATION DEFAULT FONT
        self.setFont(Font('Roboto', pixelSize=12))

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

        style = EddyProxyStyle('Fusion')
        self.setStyle(style)
        self.setStyleSheet(style.stylesheet)

        #############################################
        # DRAW THE SPLASH SCREEN
        #################################

        splash = None
        if not self.options.isSet(CommandLineParser.NO_SPLASH):
            splash = Splash(mtime=2)
            splash.show()

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

        settings = QtCore.QSettings()

        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.
            examples = list(filter(lambda path: fexists(path) and faccess(path), [
                expandPath('@examples/Animals{}'.format(File.Graphol.extension)),
                expandPath('@examples/Diet{}'.format(File.Graphol.extension)),
                expandPath('@examples/Family{}'.format(File.Graphol.extension)),
                expandPath('@examples/LUBM{}'.format(File.Graphol.extension)),
                expandPath('@examples/Pizza{}'.format(File.Graphol.extension)),
            ]))
            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', None, str) or []):
                if fexists(path) and path not in projects:
                    projects.append(path)
            settings.setValue('project/recent', projects)
            settings.sync()

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

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

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

        if splash and not self.options.isSet(CommandLineParser.NO_SPLASH):
            splash.sleep()
            splash.close()
Exemple #30
0
        def make_installer(self):
            """Create a Windows installer using InnoSetup."""
            import yaml

            with open(os.path.join('support', 'innosetup', 'build.yaml'),
                      'r') as f:
                config = yaml.safe_load(f)
            if 'scripts' not in config:
                print(
                    "ERROR: invalid config file: could not find 'scripts' section"
                )
                sys.exit(1)
            if not len(config['scripts']):
                print(
                    "ERROR: invalid config file: no entry found in 'scripts' section"
                )
                sys.exit(1)

            # Location of the InnoSetup Compiler program taken from environment.
            config['iscc'] = os.environ.get('ISCC_EXE', config['iscc'])

            if 'iscc' not in config:
                print(
                    "ERROR: invalid config file: could not find 'iscc' entry")
                sys.exit(1)
            if not config['iscc'].lower().endswith('iscc.exe'):
                print("ERROR: invalid location for the ISCC.exe program: %s" %
                      config['iscc'])
                sys.exit(1)
            if not fexists(os.path.join('support', 'innosetup',
                                        config['iscc'])):
                print("ERROR: invalid config file: '%s' is not a file" %
                      config['iscc'])
                sys.exit(1)

            # Disable installation of 64 bit executables on 32 bit Windows
            architecturesAllowed = 'x64' if platform.architecture(
            )[0] == '64bit' else ''

            # Build each given innosetup script
            for filename in config['scripts']:
                script_file = os.path.join('support', 'innosetup', filename)
                distutils.log.info("building: %s" % script_file)

                try:
                    cmd = [
                        config['iscc'],
                        script_file,
                        '/Q',
                        '/O{0}'.format(self.dist_dir),
                        '/dEDDY_APPID={0}'.format(APPID),
                        '/dEDDY_APPNAME={0}'.format(APPNAME),
                        '/dEDDY_ARCHITECTURE={0}'.format(EXEC_ARCH),
                        '/dEDDY_ARCHITECTURES_ALLOWED={0}'.format(
                            architecturesAllowed),
                        '/dEDDY_BUGTRACKER={0}'.format(BUG_TRACKER),
                        '/dEDDY_BUILD_PATH={0}'.format(
                            os.path.join(self.distpath, DIST_NAME)),
                        '/dEDDY_COPYRIGHT={0}'.format(COPYRIGHT),
                        '/dEDDY_DOWNLOAD_URL={0}'.format(GRAPHOL_HOME),
                        '/dEDDY_EXECUTABLE={0}'.format(EXEC_NAME),
                        '/dEDDY_GRAPHOL_URL={0}'.format(GRAPHOL_HOME),
                        '/dEDDY_LICENSE={0}'.format(LICENSE.lower()),
                        '/dEDDY_ORGANIZATION={0}'.format(ORGANIZATION),
                        '/dEDDY_ORGANIZATION_URL={0}'.format(ORGANIZATION_URL),
                        '/dEDDY_PROJECT_HOME={0}'.format(PROJECT_HOME),
                        '/dEDDY_VERSION={0}'.format(VERSION),
                    ]
                    subprocess.call(cmd)
                except Exception as e:
                    distutils.log.error('Failed to build {0}: {1}'.format(
                        script_file, e))
Exemple #31
0
 def assertFileExists(self, filepath, msg=None):
     """Assert for the given path to represent a file"""
     if not fexists(filepath):
         standardMsg = '%s is not a file' % safe_repr(expandPath(filepath))
         self.fail(self._formatMessage(msg, standardMsg))
Exemple #32
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