Exemplo n.º 1
0
    def __init__(self, parent=None):
        channels = self.get_option('channels', ['anaconda', 'spyder-ide'])
        active_channels = self.get_option('active_channels',
                                          ['anaconda', 'spyder-ide'])
        CondaPackagesWidget.__init__(
            self,
            parent=parent,
            channels=channels,
            active_channels=active_channels,
        )
        SpyderPluginMixin.__init__(self, parent)

        self.root_env = 'root'
        self._prefix_to_set = self.get_environment_prefix()

        # Initialize plugin
        self.initialize_plugin()
Exemplo n.º 2
0
    def __init__(self):
        super(PackagesTab, self).__init__()

        self.api = AnacondaAPI()
        self.path = None
        self.project = None

        # Widgets
        self.list_environments = EditableList(title='Environments')
        self.list_commands = EditableList(title='Commands', min_items=0)
        self.package_manager = CondaPackagesWidget(
            self,
            setup=False,
            data_directory=CHANNELS_PATH,
        )

        # Widget setup
        self.list_environments.button_add.clicked.disconnect()
        self.list_environments.button_edit.setVisible(False)

        # Layout
        top_layout = QHBoxLayout()
        top_layout.addWidget(self.list_environments)
        top_layout.addStretch()
        top_layout.addWidget(self.list_commands)
        top_layout.addStretch()

        main_layout = QVBoxLayout()
        main_layout.addLayout(top_layout)
        main_layout.addWidget(self.package_manager)
        self.setLayout(main_layout)

        # Signals
        self.list_commands.sig_item_removed.connect(self.edit_commands)
        self.list_commands.sig_item_edited.connect(self.add_command)
        self.list_commands.sig_item_selected.connect(self.select_command)

        self.list_environments.button_add.clicked.connect(self.add_environment)
        self.list_environments.sig_item_removed.connect(
            self.remove_environment)
        self.list_environments.sig_item_selected.connect(
            self.choose_environment)

        self.package_manager.sig_channels_updated.connect(self.set_channels)
Exemplo n.º 3
0
    def __init__(self):
        super(MainWindow, self).__init__()

        # Variables
        self.file_menu = None
        self.file_menu_actions = []
        self.tools_menu = None
        self.tools_menu_actions = []
        self.help_menu = None
        self.help_menu_actions = []
        self.menulist = []

        # Widgets
        self.packages = CondaPackagesWidget(self)

        # Widget setup
        self.setWindowTitle('Conda Package Manager {0}'.format(__version__))
        self.setCentralWidget(self.packages)

        self.setup_window()
Exemplo n.º 4
0
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        # Variables
        self.file_menu = None
        self.file_menu_actions = []
        self.tools_menu = None
        self.tools_menu_actions = []
        self.help_menu = None
        self.help_menu_actions = []
        self.menulist = []

        # Widgets
        self.packages = CondaPackagesWidget(self)

        # Widget setup
        self.setWindowTitle('Conda Package Manager {0}'.format(__version__))
        self.setCentralWidget(self.packages)

        self.setup_window()

    def setup_window(self):
        """ """
        self.close_action = create_action(self, _("&Quit"),
                                          triggered=self.close)
        self.file_menu_actions.append(self.close_action)
        self.file_menu = self.menuBar().addMenu(_("&File"))
        add_actions(self.file_menu, self.file_menu_actions)

        # Environments
        self.add_env_action = create_action(self, _("&Add"),
                                            triggered=self.add_env)
        self.clone_env_action = create_action(self, _("&Clone"),
                                              triggered=self.clone_env)
        self.remove_env_action = create_action(self, _("&Remove"),
                                               triggered=self.remove_env)
        self.envs_list_menu = QMenu(_('Environments'))
        self.envs_menu_actions = [self.add_env_action, self.clone_env_action,
                                  self.remove_env_action, None,
                                  self.envs_list_menu]
        self.envs_menu = self.menuBar().addMenu(_("&Environments"))
        add_actions(self.envs_menu, self.envs_menu_actions)
        self.update_env_menu()

        # Channels
        self.envs_menu = self.menuBar().addMenu(_("&Channels"))

        # Tools
        self.preferences_action = create_action(self,
                                                _("&Preferences"),
                                                triggered=self.preferences)
        self.tools_menu_actions.append(self.preferences_action)
        self.tools_menu = self.menuBar().addMenu(_("&Tools"))
        add_actions(self.tools_menu, self.tools_menu_actions)

        # Help
        self.report_action = create_action(self,
                                           _("&Report issue"),
                                           triggered=self.report_issue)
        self.about_action = create_action(self, _("&About"),
                                          triggered=self.about)
        self.help_menu_actions.append(self.report_action)
        self.help_menu_actions.append(self.about_action)
        self.help_menu = self.menuBar().addMenu(_("&Help"))
        add_actions(self.help_menu, self.help_menu_actions)

        self.setWindowIcon(get_icon('condapackages.png'))

    def update_env_menu(self):
        """ """
        envs_list_actions = []
        envs = self.get_enviroments()
        self.envs_list_menu.clear()
        for env in envs:
            def trigger(value=False, e=env):
                return lambda: self.set_environments(e)
            a = create_action(self, env, triggered=trigger())
            envs_list_actions.append(a)
        add_actions(self.envs_list_menu, envs_list_actions)

    def get_enviroments(self, path=None):
        """ """
        return ['root'] + self.packages.get_environments()

    def set_environments(self, prefix):
        """ """
        self.packages.set_environment(prefix=prefix)

    def add_env(self):
        """ """
        # TODO:

    def clone_env(self):
        """ """
        # TODO:

    def remove_env(self):
        """ """
        # TODO:

    def preferences(self):
        """ """
        # TODO:

    def report_issue(self):
        if PY3:
            from urllib.parse import quote
        else:
            from urllib import quote     # analysis:ignore

        issue_template = """\
## Description

- *What steps will reproduce the problem?*
1.
2.
3.

- *What is the expected output? What do you see instead?*


- *Please provide any additional information below*


## Version and main components

- Conda Package Manager Version:  {version}
- Conda Version:  {conda version}
- Python Version:  {python version}
- Qt Version    :  {Qt version}
- QtPy Version    :  {QtPy version}
"""
        url = QUrl("https://github.com/spyder-ide/conda-manager/issues/new")
        url.addEncodedQueryItem("body", quote(issue_template))
        QDesktopServices.openUrl(url)

    def about(self):
        """About Conda Package Manager."""
        var = {'github': 'https://github.com/spyder-ide/conda-manager'}

        QMessageBox.about(self, _("About"), """
            <p><b>Conda Package Manager</b></p>

            <p>Copyright &copy; 2015 The Spyder Development Team<br>
            Licensed under the terms of the MIT License</p>

            <p>Created by Gonzalo Pe&ntilde;a-Castellanos<br>
            Developed and maintained by the Spyder Development Team.</p>

            <p>For bug reports and feature requests, please go
            to our <a href="{github}">Github website</a>.</p>

            <p>This project is part of a larger effort to promote and
            facilitate the use of Python for scientific and engineering
            software development. The popular Python distributions
            <a href="http://continuum.io/downloads">Anaconda</a>,
            <a href="https://winpython.github.io/">WinPython</a> and
            <a href="http://code.google.com/p/pythonxy/">Python(x,y)</a>
            also contribute to this plan.</p>
            """.format(**var))

    def closeEvent(self, event):
        """ """
        if self.packages.busy:
            answer = QMessageBox.question(
                self,
                'Quit Conda Manager?',
                'Conda is still busy.\n\nDo you want to quit?',
                buttons=QMessageBox.Yes | QMessageBox.No)

            if answer == QMessageBox.Yes:
                QMainWindow.closeEvent(self, event)
                # Do some cleanup?
            else:
                event.ignore()
        else:
            QMainWindow.closeEvent(self, event)
Exemplo n.º 5
0
    def __init__(self, parent=None):
        super(EnvironmentsTab, self).__init__(parent)

        self.api = AnacondaAPI()
        self.last_env_prefix = None
        self.last_env_name = None
        self.previous_environments = None
        self.tracker = GATracker()
        self.metadata = {}

        active_channels = CONF.get('main',  'conda_active_channels', tuple())
        channels = CONF.get('main',  'conda_channels', tuple())
        conda_url = CONF.get('main',  'conda_url',
                             'https:/conda.anaconda.org')
        conda_api_url = CONF.get('main',  'anaconda_api_url',
                                 'https://api.anaconda.org')

        # Widgets
        self.button_clone = ButtonEnvironmentPrimary("Clone")
        self.button_create = ButtonEnvironmentPrimary("Create")
        self.button_remove = ButtonEnvironmentCancel("Remove")
        self.frame_environments = FrameEnvironments(self)
        self.frame_environments_list = FrameEnvironmentsList(self)
        self.frame_environments_list_buttons = FrameEnvironmentsListButtons(self)
        self.frame_environments_packages = FrameEnvironmentsPackages(self)
        self.list_environments = ListWidgetEnvironment()
        self.packages_widget = CondaPackagesWidget(
            self,
            setup=False,
            active_channels=active_channels,
            channels=channels,
            data_directory=CHANNELS_PATH,
            conda_api_url=conda_api_url,
            conda_url=conda_url)
        self.menu_list = QMenu()
        self.text_search = LineEditSearch()
        self.timer_environments = QTimer()

        # Widgets setup
        self.list_environments.setAttribute(Qt.WA_MacShowFocusRect, False)
        self.list_environments.setContextMenuPolicy(Qt.CustomContextMenu)
        self.packages_widget.textbox_search.setAttribute(
            Qt.WA_MacShowFocusRect, False)
        self.packages_widget.textbox_search.set_icon_visibility(False)
        self.text_search.setPlaceholderText("Search Environments")
        self.text_search.setAttribute(Qt.WA_MacShowFocusRect, False)
        self.timer_environments.setInterval(5000)

        # Layouts
        environments_layout = QVBoxLayout()
        environments_layout.addWidget(self.text_search)

        buttons_layout = QHBoxLayout()
        buttons_layout.addWidget(self.button_create)
        buttons_layout.addWidget(self.button_clone)
        buttons_layout.addWidget(self.button_remove)
        buttons_layout.setContentsMargins(0, 0, 0, 0)

        list_buttons_layout = QVBoxLayout()
        list_buttons_layout.addWidget(self.list_environments)
        list_buttons_layout.addLayout(buttons_layout)
        self.frame_environments_list_buttons.setLayout(list_buttons_layout)
        list_buttons_layout.setContentsMargins(0, 0, 0, 0)
        environments_layout.addWidget(self.frame_environments_list_buttons)

        self.frame_environments_list.setLayout(environments_layout)

        packages_layout = QHBoxLayout()
        packages_layout.addWidget(self.packages_widget)
        packages_layout.setContentsMargins(0, 0, 0, 0)
        self.frame_environments_packages.setLayout(packages_layout)

        main_layout = QHBoxLayout()
        main_layout.addWidget(self.frame_environments_list, 1)
        main_layout.addWidget(self.frame_environments_packages, 3)
        main_layout.setContentsMargins(0, 0, 0, 0)
        self.frame_environments.setLayout(main_layout)

        layout = QHBoxLayout()
        layout.addWidget(self.frame_environments)
        self.setLayout(layout)

        # Signals
        self.button_clone.clicked.connect(self.clone_environment)
        self.button_create.clicked.connect(self.create_environment)
        self.button_remove.clicked.connect(self.remove_environment)
        self.list_environments.sig_item_selected.connect(
            self.load_environment)
        self.packages_widget.sig_packages_ready.connect(self.refresh)
        self.packages_widget.sig_channels_updated.connect(self.update_channels)
#        self.packages_widget.sig_environment_cloned.connect(
#            self._environment_created)
#        self.packages_widget.sig_environment_created.connect(
#            self._environment_created)
#        self.packages_widget.sig_environment_removed.connect(
#            self._environment_removed)
        self.text_search.textChanged.connect(self.filter_environments)
        self.timer_environments.timeout.connect(self.refresh_environments)
        self.packages_widget.sig_process_cancelled.connect(
            lambda: self.update_visibility(True))
Exemplo n.º 6
0
class EnvironmentsTab(WidgetBase):
    """
    This tab holds the list of named and application environments in the local
    machine.

    Available options include, `create`, `clone` and `remove` and package
    management.
    """
    BLACKLIST = ['anaconda-navigator']  # Do not show in package manager.

    sig_status_updated = Signal(object, object, object, object)

    def __init__(self, parent=None):
        super(EnvironmentsTab, self).__init__(parent)

        self.api = AnacondaAPI()
        self.last_env_prefix = None
        self.last_env_name = None
        self.previous_environments = None
        self.tracker = GATracker()
        self.metadata = {}

        active_channels = CONF.get('main',  'conda_active_channels', tuple())
        channels = CONF.get('main',  'conda_channels', tuple())
        conda_url = CONF.get('main',  'conda_url',
                             'https:/conda.anaconda.org')
        conda_api_url = CONF.get('main',  'anaconda_api_url',
                                 'https://api.anaconda.org')

        # Widgets
        self.button_clone = ButtonEnvironmentPrimary("Clone")
        self.button_create = ButtonEnvironmentPrimary("Create")
        self.button_remove = ButtonEnvironmentCancel("Remove")
        self.frame_environments = FrameEnvironments(self)
        self.frame_environments_list = FrameEnvironmentsList(self)
        self.frame_environments_list_buttons = FrameEnvironmentsListButtons(self)
        self.frame_environments_packages = FrameEnvironmentsPackages(self)
        self.list_environments = ListWidgetEnvironment()
        self.packages_widget = CondaPackagesWidget(
            self,
            setup=False,
            active_channels=active_channels,
            channels=channels,
            data_directory=CHANNELS_PATH,
            conda_api_url=conda_api_url,
            conda_url=conda_url)
        self.menu_list = QMenu()
        self.text_search = LineEditSearch()
        self.timer_environments = QTimer()

        # Widgets setup
        self.list_environments.setAttribute(Qt.WA_MacShowFocusRect, False)
        self.list_environments.setContextMenuPolicy(Qt.CustomContextMenu)
        self.packages_widget.textbox_search.setAttribute(
            Qt.WA_MacShowFocusRect, False)
        self.packages_widget.textbox_search.set_icon_visibility(False)
        self.text_search.setPlaceholderText("Search Environments")
        self.text_search.setAttribute(Qt.WA_MacShowFocusRect, False)
        self.timer_environments.setInterval(5000)

        # Layouts
        environments_layout = QVBoxLayout()
        environments_layout.addWidget(self.text_search)

        buttons_layout = QHBoxLayout()
        buttons_layout.addWidget(self.button_create)
        buttons_layout.addWidget(self.button_clone)
        buttons_layout.addWidget(self.button_remove)
        buttons_layout.setContentsMargins(0, 0, 0, 0)

        list_buttons_layout = QVBoxLayout()
        list_buttons_layout.addWidget(self.list_environments)
        list_buttons_layout.addLayout(buttons_layout)
        self.frame_environments_list_buttons.setLayout(list_buttons_layout)
        list_buttons_layout.setContentsMargins(0, 0, 0, 0)
        environments_layout.addWidget(self.frame_environments_list_buttons)

        self.frame_environments_list.setLayout(environments_layout)

        packages_layout = QHBoxLayout()
        packages_layout.addWidget(self.packages_widget)
        packages_layout.setContentsMargins(0, 0, 0, 0)
        self.frame_environments_packages.setLayout(packages_layout)

        main_layout = QHBoxLayout()
        main_layout.addWidget(self.frame_environments_list, 1)
        main_layout.addWidget(self.frame_environments_packages, 3)
        main_layout.setContentsMargins(0, 0, 0, 0)
        self.frame_environments.setLayout(main_layout)

        layout = QHBoxLayout()
        layout.addWidget(self.frame_environments)
        self.setLayout(layout)

        # Signals
        self.button_clone.clicked.connect(self.clone_environment)
        self.button_create.clicked.connect(self.create_environment)
        self.button_remove.clicked.connect(self.remove_environment)
        self.list_environments.sig_item_selected.connect(
            self.load_environment)
        self.packages_widget.sig_packages_ready.connect(self.refresh)
        self.packages_widget.sig_channels_updated.connect(self.update_channels)
#        self.packages_widget.sig_environment_cloned.connect(
#            self._environment_created)
#        self.packages_widget.sig_environment_created.connect(
#            self._environment_created)
#        self.packages_widget.sig_environment_removed.connect(
#            self._environment_removed)
        self.text_search.textChanged.connect(self.filter_environments)
        self.timer_environments.timeout.connect(self.refresh_environments)
        self.packages_widget.sig_process_cancelled.connect(
            lambda: self.update_visibility(True))

    # --- Helpers
    # -------------------------------------------------------------------------
    def update_visibility(self, enabled=True):
        self.button_create.setDisabled(not enabled)
        self.button_remove.setDisabled(not enabled)
        self.button_clone.setDisabled(not enabled)
        self.list_environments.setDisabled(not enabled)
        update_pointer()

    def update_style_sheet(self, style_sheet=None):
        if style_sheet is None:
            style_sheet = load_style_sheet()

        self.setStyleSheet(style_sheet)
        self.menu_list.setStyleSheet(style_sheet)
        self.list_environments.setFrameStyle(QFrame.NoFrame)
        self.list_environments.setFrameShape(QFrame.NoFrame)
        self.packages_widget.table.setFrameStyle(QFrame.NoFrame)
        self.packages_widget.table.setFrameShape(QFrame.NoFrame)
        self.packages_widget.layout().setContentsMargins(0, 0, 0, 0)

        size = QSize(16, 16)

        palette = {
            'icon.action.not_installed': QIcon(images.CONDA_MANAGER_NOT_INSTALLED).pixmap(size),
            'icon.action.installed': QIcon(images.CONDA_MANAGER_INSTALLED).pixmap(size),
            'icon.action.remove': QIcon(images.CONDA_MANAGER_REMOVE).pixmap(size),
            'icon.action.add': QIcon(images.CONDA_MANAGER_ADD).pixmap(size),
            'icon.action.upgrade': QIcon(images.CONDA_MANAGER_UPGRADE).pixmap(size),
            'icon.action.downgrade': QIcon(images.CONDA_MANAGER_DOWNGRADE).pixmap(size),
            'icon.upgrade.arrow': QIcon(images.CONDA_MANAGER_UPGRADE_ARROW).pixmap(size),
            'background.remove': QColor(0, 0, 0, 0),
            'background.install': QColor(0, 0, 0, 0),
            'background.upgrade': QColor(0, 0, 0, 0),
            'background.downgrade': QColor(0, 0, 0, 0),
            'foreground.not.installed': QColor("#666"),
            'foreground.upgrade': QColor("#0071a0"),
            }

        self.packages_widget.update_style_sheet(
            style_sheet=style_sheet,
            extra_dialogs={'cancel_dialog': ClosePackageManagerDialog,
                           'apply_actions_dialog': ActionsDialog,
                           'message_box_error': MessageBoxError,
                           },
            palette=palette,
            )

    def get_environments(self):
        """
        Return an ordered dictionary of all existing named environments as
        keys and the prefix as items.

        The dictionary includes the root environment as the first entry.
        """
        environments = OrderedDict()
        environments_prefix = sorted(self.api.conda_get_envs())
        environments['root'] = self.api.ROOT_PREFIX

        for prefix in environments_prefix:
            name = os.path.basename(prefix)
            environments[name] = prefix

        return environments

    def refresh_environments(self):
        """
        Check every `timer_refresh_envs` amount of miliseconds for newly
        created environments and update the list if new ones are found.
        """
        environments = self.get_environments()
        if self.previous_environments is None:
            self.previous_environments = environments.copy()

        if self.previous_environments != environments:
            self.previous_environments = environments.copy()
            self.setup_tab()

    def open_environment_in(self, which):
        environment_prefix = self.list_environments.currentItem().prefix()
        environment_name = self.list_environments.currentItem().text()
        logger.debug("%s, %s", which, environment_prefix)

        if environment_name == 'root':
            environment_prefix = None

        if which == 'terminal':
            launch.console(environment_prefix)
        else:
            launch.py_in_console(environment_prefix, which)

    def set_last_active_prefix(self):
        current_item = self.list_environments.currentItem()
        if current_item:
            self.last_env_prefix = getattr(current_item, '_prefix')
        else:
            self.last_env_prefix = self.api.ROOT_PREFIX
        CONF.set('main', 'last_active_prefix', self.last_env_prefix)

    def setup_tab(self, metadata={}, load_environment=True):
        if metadata:
            self.metadata = metadata

        # show_apps = CONF.get('main', 'show_application_environments')
        envs = self.get_environments()
        self.timer_environments.start()
        self.menu_list.clear()
        menu_item = self.menu_list.addAction('Open Terminal')
        menu_item.triggered.connect(
            lambda: self.open_environment_in('terminal'))

        for word in ['Python', 'IPython', 'Jupyter Notebook']:
            menu_item = self.menu_list.addAction("Open with " + word)
            menu_item.triggered.connect(
                lambda x, w=word: self.open_environment_in(w.lower()))

        def select(value=None, position=None):
            current_item = self.list_environments.currentItem()
            prefix = current_item.prefix()

            if isinstance(position, bool) or position is None:
                width = current_item.button_options.width()
                position = QPoint(width, 0)

#            parent_position = self.list_environments.mapToGlobal(QPoint(0, 0))
            point = QPoint(0, 0)
            parent_position = current_item.button_options.mapToGlobal(point)
            self.menu_list.move(parent_position + position)
            self.menu_list.actions()[2].setEnabled(
                launch.check_prog('ipython', prefix))
            self.menu_list.actions()[3].setEnabled(
                launch.check_prog('notebook', prefix))
            self.menu_list.exec_()

        self.set_last_active_prefix()
        self.list_environments.clear()

#        if show_apps:
#            separator_item = ListItemSeparator('My environments:')
#            self.list_environments.addItem(separator_item)

        for env in envs:
            prefix = envs[env]
            item = ListItemEnvironment(env, prefix=prefix)
            item.button_options.clicked.connect(select)
            self.list_environments.addItem(item)

#        if show_apps:
#            application_envs = self.api.get_application_environments()
#            separator_item = ListItemSeparator('Application environments:')
#            self.list_environments.addItem(separator_item)
#            for app in application_envs:
#                env_prefix = application_envs[app]
#                item = ListItemEnvironment(name=app, prefix=env_prefix)
#                item.button_options.clicked.connect(select)
#                self.list_environments.addItem(item)

        if load_environment:
            self.load_environment()
        else:
            return

        # Adjust Tab Order
        self.setTabOrder(self.text_search,
                         self.list_environments._items[0].widget)
        for i in range(len(self.list_environments._items) - 1):
            self.setTabOrder(self.list_environments._items[i].widget,
                             self.list_environments._items[i+1].widget)
        self.setTabOrder(self.list_environments._items[-1].button_name,
                         self.button_create)
        self.setTabOrder(self.button_create, self.button_clone)
        self.setTabOrder(self.button_clone, self.button_remove)
        self.setTabOrder(self.button_remove,
                         self.packages_widget.combobox_filter)
        self.setTabOrder(self.packages_widget.combobox_filter,
                         self.packages_widget.button_channels)
        self.setTabOrder(self.packages_widget.button_channels,
                         self.packages_widget.button_update)
        self.setTabOrder(self.packages_widget.button_update,
                         self.packages_widget.textbox_search)
        self.setTabOrder(self.packages_widget.textbox_search,
                         self.packages_widget.table_first_row)
        self.setTabOrder(self.packages_widget.table_last_row,
                         self.packages_widget.button_apply)
        self.setTabOrder(self.packages_widget.button_apply,
                         self.packages_widget.button_clear)
        self.setTabOrder(self.packages_widget.button_clear,
                         self.packages_widget.button_cancel)

    def filter_environments(self):
        """
        Filter displayed environments by matching search text.
        """
        text = self.text_search.text().lower()

        for i in range(self.list_environments.count()):
            item = self.list_environments.item(i)
            item.setHidden(text not in item.text().lower())

            if not item.widget.isVisible():
                item.widget.repaint()

    def load_environment(self, item=None):
        self.update_visibility(False)
        if item is None:
            item = self.list_environments.currentItem()

        if item is None or not isinstance(item, ListItemEnvironment):
            prefix = self.api.ROOT_PREFIX
            index = 0
        elif item and isinstance(item, ListItemEnvironment):
            prefix = item.prefix()
        else:
            prefix = self.last_env_prefix if self.last_env_prefix else None

        index = [i for i, it in enumerate(self.list_environments._items)
                 if prefix in it.prefix()]
        index = index[0] if len(index) else 0

        self.list_environments.setCurrentRow(index)
        self.packages_widget.set_environment(prefix=prefix)
        self.packages_widget.setup(check_updates=False,
                                   blacklist=self.BLACKLIST,
                                   metadata=self.metadata)
        self.list_environments.setDisabled(True)
        self.update_visibility(False)
        self.set_last_active_prefix()
#        update_pointer(Qt.BusyCursor)

    def refresh(self):
        self.update_visibility(True)
        self.list_environments.setDisabled(False)
        item = self.list_environments.currentItem()

        try:
            item.set_loading(False)
        except RuntimeError:
            pass
            # C/C++ object not found

        is_root = item.text() == 'root'

        self.button_remove.setDisabled(is_root)
        self.button_clone.setDisabled(is_root)

    def update_channels(self, channels, active_channels):
        """
        Save updated channels to the CONF.
        """
        CONF.set('main', 'conda_active_channels', active_channels)
        CONF.set('main', 'conda_channels', channels)

    # --- Callbacks
    # -------------------------------------------------------------------------
    def _environment_created(self, worker, output, error):
        if error:
            logger.error(str(error))

        self.update_visibility(False)
        for row, environment in enumerate(self.get_environments()):
            if worker.name == environment:
                break

        self.last_env_prefix = self.api.conda_get_prefix_envname(environment)
        self.setup_tab(load_environment=False)
        self.list_environments.setCurrentRow(row)
        self.load_environment()
        self.refresh()
        self.update_visibility(True)
        update_pointer()

    def _environment_removed(self, worker, output, error):
        self.update_visibility(True)
        if error:
            logger.error(str(error))

        self.setup_tab()
        self.list_environments.setCurrentRow(0)

    # --- Public API
    # -------------------------------------------------------------------------
    def update_domains(self, anaconda_api_url, conda_url):
        self.packages_widget.update_domains(
            anaconda_api_url=anaconda_api_url,
            conda_url=conda_url,
            )

    def create_environment(self):
        """
        Create new basic environment with selectable python version.

        Actually makes new env on disc, in directory within the project
        whose name depends on the env name. New project state is saved.
        Should also sync to spec file.
        """
        dlg = CreateEnvironmentDialog(parent=self,
                                      environments=self.get_environments())
        self.tracker.track_page('/environments/create',
                                pagetitle='Create new environment dialog')

        if dlg.exec_():
            name = dlg.text_name.text().strip()
            pyver = dlg.combo_version.currentText()

            if name:
                logger.debug(str('{0}, {1}'.format(name, pyver)))

                self.update_visibility(False)
                update_pointer(Qt.BusyCursor)

                if pyver:
                    pkgs = ['python=' + pyver, 'jupyter']
                else:
                    pkgs = ['jupyter']

                channels = self.packages_widget._active_channels
                logger.debug(str((name, pkgs, channels)))
                self.update_visibility(False)
                worker = self.packages_widget.create_environment(name=name, 
                                                                 packages=pkgs)
#                worker = self.api.conda_create(name=name, pkgs=pkgs,
#                                               channels=channels)
                worker.name = name
                worker.sig_finished.connect(self._environment_created)
        self.tracker.track_page('/environments')

    def remove_environment(self):
        """
        Clone currently selected environment.
        """
        current_item = self.list_environments.currentItem()
        if current_item is not None:
            name = current_item.text()

            if name == 'root':
                return

            dlg = RemoveEnvironmentDialog(environment=name)
            self.tracker.track_page('/environments/remove',
                                    pagetitle='Remove environment dialog')
            if dlg.exec_():
                logger.debug(str(name))
                self.update_visibility(False)
                update_pointer(Qt.BusyCursor)
                worker = self.packages_widget.remove_environment(name=name)
#                worker = self.api.conda_remove(name=name, all_=True)
                worker.sig_finished.connect(self._environment_removed)
#                self.sig_status_updated.emit('Deleting environment '
#                                             '"{0}"'.format(name),
#                                             0, -1, -1)
            self.tracker.track_page('/environments')

    def clone_environment(self):
        """
        Clone currently selected environment.
        """
        current_item = self.list_environments.currentItem()
        if current_item is not None:
            current_name = current_item.text()
            dlg = CloneEnvironmentDialog(parent=self,
                                         environments=self.get_environments())
            self.tracker.track_page('/environments/clone',
                                    pagetitle='Clone environment dialog')

            if dlg.exec_():
                name = dlg.text_name.text().strip()

                if name and current_name:
                    logger.debug(str("{0}, {1}".format(current_name, name)))

                    self.update_visibility(False)
                    update_pointer(Qt.BusyCursor)
                    worker = self.packages_widget.clone_environment(clone=current_name,
                                                                    name=name)
#                    worker = self.api.conda_clone(current_name, name=name)
                    worker.name = name
                    worker.sig_finished.connect(self._environment_created)
            self.tracker.track_page('/environments')

    def import_environment(self):
        """
Exemplo n.º 7
0
class PackagesTab(QWidget):
    """
    Packages, environments and commands tab widget.
    """
    sig_status_updated = Signal(object, object, object, object)
    sig_updated = Signal(object, object)
    sig_project_commands_updated = Signal(object, object)
    sig_apps_updated = Signal()

    def __init__(self):
        super(PackagesTab, self).__init__()

        self.api = AnacondaAPI()
        self.path = None
        self.project = None

        # Widgets
        self.list_environments = EditableList(title='Environments')
        self.list_commands = EditableList(title='Commands', min_items=0)
        self.package_manager = CondaPackagesWidget(
            self,
            setup=False,
            data_directory=CHANNELS_PATH,
        )

        # Widget setup
        self.list_environments.button_add.clicked.disconnect()
        self.list_environments.button_edit.setVisible(False)

        # Layout
        top_layout = QHBoxLayout()
        top_layout.addWidget(self.list_environments)
        top_layout.addStretch()
        top_layout.addWidget(self.list_commands)
        top_layout.addStretch()

        main_layout = QVBoxLayout()
        main_layout.addLayout(top_layout)
        main_layout.addWidget(self.package_manager)
        self.setLayout(main_layout)

        # Signals
        self.list_commands.sig_item_removed.connect(self.edit_commands)
        self.list_commands.sig_item_edited.connect(self.add_command)
        self.list_commands.sig_item_selected.connect(self.select_command)

        self.list_environments.button_add.clicked.connect(self.add_environment)
        self.list_environments.sig_item_removed.connect(
            self.remove_environment)
        self.list_environments.sig_item_selected.connect(
            self.choose_environment)

        self.package_manager.sig_channels_updated.connect(self.set_channels)

    def load_information(self, path, project=None):
        """
        """
        self.path = path

        if project is None:
            project = self.api.load_project(path)

        logger.debug(str((path, project.name)))
        self.project = project

        # Load commands
        commands = project.commands
        self.list_commands.clear()

        for command in commands:
            item = QListWidgetItem(command)
            self.list_commands.add(item)
        self.list_commands.setCurrentRow(0)

        # Load environments
        environments = project.environments
        self.list_environments.clear()

        selected_row = 0
        for i, environment in enumerate(environments):
            item = QListWidgetItem(environment)
            self.list_environments.add(item)
            if environment == project.default_environment:
                selected_row = i
        self.list_environments.setCurrentRow(selected_row)

        # Load channels
        self.package_manager.set_environment(prefix=project.env_prefix(path))
        self.package_manager.update_channels(project.default_channels,
                                             project.default_channels)

    def set_channels(self, channels, active_channels):
        """
        """
        logger.debug(channels)
        self.project.default_channels = list(active_channels)
        self.project.save(self.path)

    # --- Environments
    # -------------------------------------------------------------------------
    def add_environment(self, text=None, pyver=None):
        """
        Create new basic environment with selectable python version.

        Actually makes new env on disc, in directory within the project
        whose name depends on the env name. New project state is saved.
        Should also sync to spec file.
        """
        dlg = CreateEnvironmentDialog(parent=self,
                                      envs=self.project.environments)

        if dlg.exec_():
            text = dlg.text_name.text().strip()
            pyver = dlg.combo_version.currentText()

        if text:
            self.setEnabled(False)
            QApplication.setOverrideCursor(Qt.BusyCursor)

            # FIXME: This does not seem like a very safe way. What if it fails?
            self.project.default_environment = text
            self.project.environments[text] = "{0}.yaml".format(text)
            prefix = self.project.env_prefix(self.path)

            if pyver:
                pkgs = ['python=' + pyver, 'jupyter']
            else:
                pkgs = ['jupyter']

            channels = self.project.default_channels
            logger.debug(str((prefix, pkgs, channels)))
            worker = self.api.conda_create(prefix=prefix,
                                           pkgs=pkgs,
                                           channels=channels)
            worker.text = text
            worker.sig_finished.connect(self._environment_added)

    def _environment_added(self, worker, output, error):
        """
        Callback for worker after envrionemnt creation has finished.
        """
        text = worker.text
        item = QListWidgetItem(text)
        self.list_environments.add(item)
        self.list_environments.setCurrentRow(
            len(self.project.environments) - 1)
        self.setEnabled(True)
        self.project.save(self.path)
        self.choose_environment()
        QApplication.restoreOverrideCursor()

    def remove_environment(self, item):
        """
        Delete environment from project and project directory.
        """
        text = item.text()
        self.project.default_environment = text
        path = self.project.env_prefix(self.path)
        logger.debug(str((path, text)))
        shutil.rmtree(path)
        self.project.environments.pop(text)
        self.project.save(self.path)
        self.choose_environment()

    def choose_environment(self):
        """
        The user has picked a different environment.

        Refresh the package list and save the new state of the project.
        """
        current_item_text = self.list_environments.currentItem().text()
        logger.debug(current_item_text)
        self.project.default_environment = current_item_text
        self.project.save(self.path)
        prefix = self.project.env_prefix(self.path)
        self.package_manager.set_environment(prefix=prefix)
        self.package_manager.setup()

    # --- Commands
    # -------------------------------------------------------------------------
    def add_command(self, command=None):
        """
        Add a new command in the commands list. Adds to the bottom of the list.
        """
        if command:
            item = QListWidgetItem(command)
            self.list_commands.add(item)

        commands = [
            self.list_commands.item(i).text()
            for i in range(self.list_commands.count())
        ]
        self.project.commands = commands
        self.project.save(self.path)
        self.sig_project_commands_updated.emit(self.path,
                                               self.project.commands)
        logger.debug(self.project.commands)

    def edit_commands(self):
        """
        """
        commands = [
            self.list_commands.item(i).text()
            for i in range(self.list_commands.count())
        ]
        self.project.commands = commands
        self.project.save(self.path)
        self.sig_project_commands_updated.emit(self.path,
                                               self.project.commands)
        logger.debug(self.project.commands)

    def select_command(self):
        """
        """
        self.sig_apps_updated.emit()
        logger.debug(self.project.commands)