Exemplo n.º 1
0
class KiteCompletionPlugin(SpyderCompletionPlugin):
    COMPLETION_CLIENT_NAME = 'kite'

    def __init__(self, parent):
        SpyderCompletionPlugin.__init__(self, parent)
        self.available_languages = []
        self.client = KiteClient(None)
        self.kite_process = None
        self.client.sig_client_started.connect(self.http_client_ready)
        self.client.sig_response_ready.connect(
            functools.partial(self.sig_response_ready.emit,
                              self.COMPLETION_CLIENT_NAME))

    @Slot(list)
    def http_client_ready(self, languages):
        logger.debug('Kite client is available for {0}'.format(languages))
        self.available_languages = languages
        self.sig_plugin_ready.emit(self.COMPLETION_CLIENT_NAME)

    def send_request(self, language, req_type, req, req_id):
        if language in self.available_languages:
            self.client.sig_perform_request.emit(req_id, req_type, req)

    def start_client(self, language):
        return language in self.available_languages

    def start(self):
        installed, path = self._check_if_kite_installed()
        if installed:
            logger.debug('Kite was found on the system: {0}'.format(path))
            running = self._check_if_kite_running()
            if not running:
                logger.debug('Starting Kite service...')
                self.kite_process = run_program(path)
            self.client.start()

    def shutdown(self):
        self.client.stop()
        if self.kite_process is not None:
            self.kite_process.kill()

    def _check_if_kite_installed(self):
        path = ''
        if os.name == 'nt':
            path = 'C:\\Program Files\\Kite\\kited.exe'
        elif sys.platform.startswith('linux'):
            path = osp.expanduser('~/.local/share/kite/kited')
        elif sys.platform == 'darwin':
            path = '/opt/kite/kited'
        return osp.exists(osp.realpath(path)), path

    def _check_if_kite_running(self):
        running = False
        for proc in psutil.process_iter(attrs=['pid', 'name', 'username']):
            if 'kited' in proc.name():
                logger.debug('Kite process already '
                             'running with PID {0}'.format(proc.pid))
                running = True
                break
        return running
Exemplo n.º 2
0
    def __init__(self, parent):
        SpyderCompletionPlugin.__init__(self, parent)
        self.available_languages = []
        self.client = KiteClient(None)
        self.kite_process = None

        # Installation dialog
        self.installation_thread = KiteInstallationThread(self)
        self.installer = KiteInstallerDialog(parent, self.installation_thread)

        # Status widget
        statusbar = parent.statusBar()  # MainWindow status bar
        self.open_file_updated = False
        self.status_widget = KiteStatusWidget(None, statusbar, self)

        # Signals
        self.client.sig_client_started.connect(self.http_client_ready)
        self.client.sig_status_response_ready[str].connect(self.set_status)
        self.client.sig_status_response_ready[dict].connect(self.set_status)
        self.client.sig_response_ready.connect(
            functools.partial(self.sig_response_ready.emit,
                              self.COMPLETION_CLIENT_NAME))
        self.installation_thread.sig_installation_status.connect(
            self.set_status)
        self.status_widget.sig_clicked.connect(self.show_installation_dialog)
        self.main.sig_setup_finished.connect(self.mainwindow_setup_finished)

        # Config
        self.update_configuration()
Exemplo n.º 3
0
 def __init__(self, parent):
     SpyderCompletionPlugin.__init__(self, parent)
     self.available_languages = []
     self.client = KiteClient(None)
     self.kite_process = None
     self.client.sig_client_started.connect(self.http_client_ready)
     self.client.sig_response_ready.connect(
         functools.partial(self.sig_response_ready.emit,
                           self.COMPLETION_CLIENT_NAME))
Exemplo n.º 4
0
 def __init__(self, parent):
     SpyderCompletionPlugin.__init__(self, parent)
     self.available_languages = []
     enable_code_snippets = CONF.get('lsp-server', 'code_snippets')
     self.client = KiteClient(None, enable_code_snippets)
     self.kite_process = None
     self.client.sig_client_started.connect(self.http_client_ready)
     self.client.sig_response_ready.connect(
         functools.partial(self.sig_response_ready.emit,
                           self.COMPLETION_CLIENT_NAME))
Exemplo n.º 5
0
class KiteCompletionPlugin(SpyderCompletionPlugin):
    COMPLETION_CLIENT_NAME = 'kite'

    def __init__(self, parent):
        SpyderCompletionPlugin.__init__(self, parent)
        self.available_languages = []
        enable_code_snippets = CONF.get('lsp-server', 'code_snippets')
        self.client = KiteClient(None, enable_code_snippets)
        self.kite_process = None
        self.client.sig_client_started.connect(self.http_client_ready)
        self.client.sig_response_ready.connect(
            functools.partial(self.sig_response_ready.emit,
                              self.COMPLETION_CLIENT_NAME))

    @Slot(list)
    def http_client_ready(self, languages):
        logger.debug('Kite client is available for {0}'.format(languages))
        self.available_languages = languages
        self.sig_plugin_ready.emit(self.COMPLETION_CLIENT_NAME)

    def send_request(self, language, req_type, req, req_id):
        if language in self.available_languages:
            self.client.sig_perform_request.emit(req_id, req_type, req)

    def start_client(self, language):
        return language in self.available_languages

    def start(self):
        installed, path = check_if_kite_installed()
        if installed:
            logger.debug('Kite was found on the system: {0}'.format(path))
            running = check_if_kite_running()
            if not running:
                logger.debug('Starting Kite service...')
                self.kite_process = run_program(path)
            self.client.start()

    def shutdown(self):
        self.client.stop()
        if self.kite_process is not None:
            self.kite_process.kill()

    def update_configuration(self):
        enable_code_snippets = CONF.get('lsp-server', 'code_snippets')
        self.client.enable_code_snippets = enable_code_snippets
Exemplo n.º 6
0
 def __init__(self, parent):
     SpyderCompletionPlugin.__init__(self, parent)
     self.available_languages = []
     self.client = KiteClient(None)
     self.kite_process = None
     self.kite_installation_thread = KiteInstallationThread(self)
     # TODO: Connect thread status to status bar
     self.kite_installer = KiteInstallerDialog(
         parent,
         self.kite_installation_thread)
     self.client.sig_client_started.connect(self.http_client_ready)
     self.client.sig_response_ready.connect(
         functools.partial(self.sig_response_ready.emit,
                           self.COMPLETION_CLIENT_NAME))
     self.kite_installation_thread.sig_installation_status.connect(
         lambda status: self.client.start() if status == FINISHED else None)
     self.main.sig_setup_finished.connect(self.mainwindow_setup_finished)
     self.update_configuration()
Exemplo n.º 7
0
class KiteCompletionPlugin(SpyderCompletionPlugin):
    COMPLETION_CLIENT_NAME = 'kite'

    def __init__(self, parent):
        SpyderCompletionPlugin.__init__(self, parent)
        self.available_languages = []
        self.client = KiteClient(None)
        self.kite_process = None
        self.client.sig_client_started.connect(self.http_client_ready)
        self.client.sig_response_ready.connect(
            functools.partial(self.sig_response_ready.emit,
                              self.COMPLETION_CLIENT_NAME))

    @Slot(list)
    def http_client_ready(self, languages):
        logger.debug('Kite client is available for {0}'.format(languages))
        self.available_languages = languages
        self.sig_plugin_ready.emit(self.COMPLETION_CLIENT_NAME)

    def send_request(self, language, req_type, req, req_id):
        if language in self.available_languages:
            self.client.sig_perform_request.emit(req_id, req_type, req)

    def start_client(self, language):
        return language in self.available_languages

    def start(self):
        installed, path = self._check_if_kite_installed()
        if installed:
            logger.debug('Kite was found on the system: {0}'.format(path))
            running = self._check_if_kite_running()
            if not running:
                logger.debug('Starting Kite service...')
                self.kite_process = run_program(path)
            self.client.start()

    def shutdown(self):
        self.client.stop()
        if self.kite_process is not None:
            self.kite_process.kill()

    def _check_if_kite_installed(self):
        path = ''
        if os.name == 'nt':
            path = 'C:\\Program Files\\Kite\\kited.exe'
        elif sys.platform.startswith('linux'):
            path = osp.expanduser('~/.local/share/kite/kited')
        elif sys.platform == 'darwin':
            path = self._locate_kite_darwin()
        return osp.exists(osp.realpath(path)), path

    def _check_if_kite_running(self):
        running = False
        for proc in psutil.process_iter(attrs=['pid', 'name', 'username']):
            if self._is_proc_kite(proc):
                logger.debug('Kite process already '
                             'running with PID {0}'.format(proc.pid))
                running = True
                break
        return running

    @staticmethod
    def _locate_kite_darwin():
        """
        Looks up where Kite.app is installed on macOS systems. The bundle ID
        is checked first and if nothing is found or an error occurs, the
        default path is used.
        """
        default_path = '/Applications/Kite.app'
        path = None
        try:
            out = subprocess.check_output(
                ['mdfind', 'kMDItemCFBundleIdentifier="com.kite.Kite"'])
            installed = len(out) > 0
            path = (out.decode('utf-8', 'replace').strip().split('\n')[0]
                    if installed else default_path)
        except (subprocess.CalledProcessError, UnicodeDecodeError) as ex:
            # Use the default path
            path = default_path
        finally:
            return path

    @staticmethod
    def _is_proc_kite(proc):
        if os.name == 'nt' or sys.platform.startswith('linux'):
            return 'kited' in proc.name()
        else:
            return proc.name() == 'Kite'
Exemplo n.º 8
0
class KiteCompletionPlugin(SpyderCompletionPlugin):
    CONF_SECTION = 'kite'
    CONF_FILE = False

    COMPLETION_CLIENT_NAME = 'kite'

    def __init__(self, parent):
        SpyderCompletionPlugin.__init__(self, parent)
        self.available_languages = []
        self.client = KiteClient(None)
        self.kite_process = None

        # Installation dialog
        self.installation_thread = KiteInstallationThread(self)
        self.installer = KiteInstallerDialog(parent, self.installation_thread)

        # Status widget
        statusbar = parent.statusBar()  # MainWindow status bar
        self.open_file_updated = False
        self.status_widget = KiteStatusWidget(None, statusbar, self)

        # Signals
        self.client.sig_client_started.connect(self.http_client_ready)
        self.client.sig_status_response_ready[str].connect(self.set_status)
        self.client.sig_status_response_ready[dict].connect(self.set_status)
        self.client.sig_response_ready.connect(
            functools.partial(self.sig_response_ready.emit,
                              self.COMPLETION_CLIENT_NAME))

        self.client.sig_response_ready.connect(self._kite_onboarding)
        self.client.sig_status_response_ready.connect(self._kite_onboarding)
        self.client.sig_onboarding_response_ready.connect(
            self._show_onboarding_file)
        self.client.sig_client_wrong_response.connect(
            self._wrong_response_error)

        self.installation_thread.sig_installation_status.connect(
            self.set_status)
        self.status_widget.sig_clicked.connect(self.show_installation_dialog)
        # self.main.sig_setup_finished.connect(self.mainwindow_setup_finished)

        # Config
        self.update_configuration()

    @Slot(list)
    def http_client_ready(self, languages):
        logger.debug('Kite client is available for {0}'.format(languages))
        self.available_languages = languages
        self.sig_plugin_ready.emit(self.COMPLETION_CLIENT_NAME)
        self._kite_onboarding()

    @Slot()
    def mainwindow_setup_finished(self):
        """
        This is called after the main window setup finishes to show Kite's
        installation dialog and onboarding if necessary.
        """
        self._kite_onboarding()

        show_dialog = self.get_option('show_installation_dialog')
        if show_dialog:
            # Only show the dialog once at startup
            self.set_option('show_installation_dialog', False)
            self.show_installation_dialog()

    @Slot(str)
    @Slot(dict)
    def set_status(self, status):
        """Show Kite status for the current file."""
        self.status_widget.set_value(status)

    @Slot()
    def show_installation_dialog(self):
        """Show installation dialog."""
        installed, path = check_if_kite_installed()
        if not installed and not running_under_pytest():
            self.installer.show()

    def send_request(self, language, req_type, req, req_id):
        if self.enabled and language in self.available_languages:
            self.client.sig_perform_request.emit(req_id, req_type, req)
        else:
            self.sig_response_ready.emit(self.COMPLETION_CLIENT_NAME, req_id,
                                         {})

    def send_status_request(self, filename):
        """Request status for the given file."""
        if not self.is_installing():
            self.client.sig_perform_status_request.emit(filename)

    def start_client(self, language):
        return language in self.available_languages

    def start(self):
        try:
            if not self.enabled:
                return
            installed, path = check_if_kite_installed()
            if not installed:
                return
            logger.debug('Kite was found on the system: {0}'.format(path))
            running = check_if_kite_running()
            if running:
                return
            logger.debug('Starting Kite service...')
            self.kite_process = run_program(path)
        except OSError:
            installed, path = check_if_kite_installed()
            logger.debug(
                'Error starting Kite service at {path}...'.format(path=path))
            if self.get_option('show_installation_error_message'):
                box = MessageCheckBox(icon=QMessageBox.Critical,
                                      parent=self.main)
                box.setWindowTitle(_("Kite installation error"))
                box.set_checkbox_text(_("Don't show again."))
                box.setStandardButtons(QMessageBox.Ok)
                box.setDefaultButton(QMessageBox.Ok)

                box.set_checked(False)
                box.set_check_visible(True)
                box.setText(
                    _("It seems that your Kite installation is faulty. "
                      "If you want to use Kite, please remove the "
                      "directory that appears bellow, "
                      "and try a reinstallation:<br><br>"
                      "<code>{kite_dir}</code>").format(
                          kite_dir=osp.dirname(path)))

                box.exec_()

                # Update checkbox based on user interaction
                self.set_option('show_installation_error_message',
                                not box.is_checked())
        finally:
            # Always start client to support possibly undetected Kite builds
            self.client.start()

    def shutdown(self):
        self.client.stop()
        if self.kite_process is not None:
            self.kite_process.kill()

    def update_configuration(self):
        self.client.enable_code_snippets = CONF.get('lsp-server',
                                                    'code_snippets')
        self.enabled = self.get_option('enable')
        self._show_onboarding = self.get_option('show_onboarding')

    def is_installing(self):
        """Check if an installation is taking place."""
        return (self.installation_thread.isRunning()
                and not self.installation_thread.cancelled)

    def installation_cancelled_or_errored(self):
        """Check if an installation was cancelled or failed."""
        return self.installation_thread.cancelled_or_errored()

    def _kite_onboarding(self):
        """Request the onboarding file."""
        # No need to check installed status,
        # since the get_onboarding_file call fails fast.
        if not self.enabled:
            return
        if not self._show_onboarding:
            return
        if self.main.is_setting_up:
            return
        if not self.available_languages:
            return
        # Don't send another request until this request fails.
        self._show_onboarding = False
        self.client.sig_perform_onboarding_request.emit()

    @Slot(str)
    def _show_onboarding_file(self, onboarding_file):
        """
        Opens the onboarding file, which is retrieved
        from the Kite HTTP endpoint. This skips onboarding if onboarding
        is not possible yet or has already been displayed before.
        """
        if not onboarding_file:
            # retry
            self._show_onboarding = True
            return
        self.set_option('show_onboarding', False)
        self.main.open_file(onboarding_file)

    @Slot(str, object)
    def _wrong_response_error(self, method, resp):
        QMessageBox.critical(
            self.main, _('Kite error'),
            _("The Kite completion engine returned an unexpected result "
              "for the request <tt>{0}</tt>: <br><br><tt>{1}</tt><br><br>"
              "Please make sure that your Kite installation is correct. "
              "In the meantime, Spyder will disable the Kite client to "
              "prevent further errors. For more information, please "
              "visit the <a href='https://help.kite.com/'>Kite help "
              "center</a>").format(method, resp))
        self.set_option('enable', False)
Exemplo n.º 9
0
class KiteCompletionPlugin(SpyderCompletionPlugin):
    CONF_SECTION = 'kite'
    CONF_FILE = False

    COMPLETION_CLIENT_NAME = 'kite'

    def __init__(self, parent):
        SpyderCompletionPlugin.__init__(self, parent)
        self.available_languages = []
        self.client = KiteClient(None)
        self.kite_process = None

        # Installation dialog
        self.installation_thread = KiteInstallationThread(self)
        self.installer = KiteInstallerDialog(parent, self.installation_thread)

        # Status widget
        statusbar = parent.statusBar()  # MainWindow status bar
        self.open_file_updated = False
        self.status_widget = KiteStatusWidget(None, statusbar, self)

        # Signals
        self.client.sig_client_started.connect(self.http_client_ready)
        self.client.sig_status_response_ready[str].connect(self.set_status)
        self.client.sig_status_response_ready[dict].connect(self.set_status)
        self.client.sig_response_ready.connect(
            functools.partial(self.sig_response_ready.emit,
                              self.COMPLETION_CLIENT_NAME))
        self.installation_thread.sig_installation_status.connect(
            self.set_status)
        self.status_widget.sig_clicked.connect(self.show_installation_dialog)
        self.main.sig_setup_finished.connect(self.mainwindow_setup_finished)

        # Config
        self.update_configuration()

    @Slot(list)
    def http_client_ready(self, languages):
        logger.debug('Kite client is available for {0}'.format(languages))
        self.available_languages = languages
        self.sig_plugin_ready.emit(self.COMPLETION_CLIENT_NAME)

    @Slot()
    def mainwindow_setup_finished(self):
        """
        This is called after the main window setup finishes to show Kite's
        installation dialog and onboarding if necessary.
        """
        show_dialog = self.get_option('show_installation_dialog')

        if show_dialog:
            # Only show the dialog once at startup
            self.set_option('show_installation_dialog', False)

            self.show_installation_dialog()

    @Slot(str)
    @Slot(dict)
    def set_status(self, status):
        """Show Kite status for the current file."""
        self.status_widget.set_value(status)

    @Slot()
    def show_installation_dialog(self):
        """Show installation dialog."""
        installed, path = check_if_kite_installed()
        if not installed and not running_under_pytest():
            self.installer.show()

    def send_request(self, language, req_type, req, req_id):
        if self.enabled and language in self.available_languages:
            self.client.sig_perform_request.emit(req_id, req_type, req)
        else:
            self.sig_response_ready.emit(self.COMPLETION_CLIENT_NAME, req_id,
                                         {})

    def send_status_request(self, filename):
        """Request status for the given file."""
        if not self.is_installing():
            self.client.sig_perform_status_request.emit(filename)

    def start_client(self, language):
        return language in self.available_languages

    def start(self):
        # Always start client to support possibly undetected Kite builds
        self.client.start()

        if not self.enabled:
            return
        installed, path = check_if_kite_installed()
        if not installed:
            return
        logger.debug('Kite was found on the system: {0}'.format(path))
        running = check_if_kite_running()
        if running:
            return
        logger.debug('Starting Kite service...')
        self.kite_process = run_program(path)

    def shutdown(self):
        self.client.stop()
        if self.kite_process is not None:
            self.kite_process.kill()

    def update_configuration(self):
        self.client.enable_code_snippets = CONF.get('lsp-server',
                                                    'code_snippets')
        self.enabled = self.get_option('enable')

    def is_installing(self):
        """Check if an installation is taking place."""
        return (self.installation_thread.isRunning()
                and not self.installation_thread.cancelled)

    def installation_cancelled_or_errored(self):
        """Check if an installation was cancelled or failed."""
        return self.installation_thread.cancelled_or_errored()
Exemplo n.º 10
0
class KiteCompletionPlugin(SpyderCompletionPlugin):
    CONF_SECTION = 'kite'
    CONF_FILE = False

    COMPLETION_CLIENT_NAME = 'kite'

    def __init__(self, parent):
        SpyderCompletionPlugin.__init__(self, parent)
        self.available_languages = []
        self.client = KiteClient(None)
        self.kite_process = None
        self.kite_installation_thread = KiteInstallationThread(self)
        # TODO: Connect thread status to status bar
        self.kite_installer = KiteInstallerDialog(
            parent,
            self.kite_installation_thread)
        self.client.sig_client_started.connect(self.http_client_ready)
        self.client.sig_response_ready.connect(
            functools.partial(self.sig_response_ready.emit,
                              self.COMPLETION_CLIENT_NAME))
        self.kite_installation_thread.sig_installation_status.connect(
            lambda status: self.client.start() if status == FINISHED else None)
        self.main.sig_setup_finished.connect(self.mainwindow_setup_finished)
        self.update_configuration()

    @Slot(list)
    def http_client_ready(self, languages):
        logger.debug('Kite client is available for {0}'.format(languages))
        self.available_languages = languages
        self.sig_plugin_ready.emit(self.COMPLETION_CLIENT_NAME)

    @Slot()
    def mainwindow_setup_finished(self):
        """
        Called when the setup of the main window finished
        to let us do onboarding if necessary
        """
        self._show_installation_dialog()

    def _show_installation_dialog(self):
        """Show installation dialog."""
        kite_installation_enabled = self.get_option('show_installation_dialog')
        installed, path = check_if_kite_installed()
        if (not installed and kite_installation_enabled
                and not running_under_pytest()):
            self.kite_installer.show()
            self.kite_installer.center()

    def send_request(self, language, req_type, req, req_id):
        if self.enabled and language in self.available_languages:
            self.client.sig_perform_request.emit(req_id, req_type, req)
        else:
            self.sig_response_ready.emit(self.COMPLETION_CLIENT_NAME,
                                         req_id, {})

    def start_client(self, language):
        return language in self.available_languages

    def start(self):
        # Always start client to support possibly undetected Kite builds
        self.client.start()

        if not self.enabled:
            return
        installed, path = check_if_kite_installed()
        if not installed:
            return
        logger.debug('Kite was found on the system: {0}'.format(path))
        running = check_if_kite_running()
        if running:
            return
        logger.debug('Starting Kite service...')
        self.kite_process = run_program(path)

    def shutdown(self):
        self.client.stop()
        if self.kite_process is not None:
            self.kite_process.kill()

    def update_configuration(self):
        self.client.enable_code_snippets = CONF.get('lsp-server',
                                                    'code_snippets')
        self.enabled = self.get_option('enable')

    def is_installing(self):
        """Check if an installation is taking place."""
        return self.kite_installation_thread.isRunning()