def get_package_versions(self, name): """ Gives all the compatible package canonical name name : str Name of the package """ package_data = self._packages.get(name) versions = [] if package_data: versions = sort_versions(list(package_data.get('versions', []))) return versions
def _multi_packages(self, logins=None, platform=None, package_type=None, type_=None, access=None, new_client=True): private_packages = {} if not new_client: time.sleep(0.3) return private_packages for login in logins: data = self._anaconda_client_api.user_packages( login=login, platform=platform, package_type=package_type, type_=type_, access=access) for item in data: name = item.get('name', '') public = item.get('public', True) package_types = item.get('package_types', []) latest_version = item.get('latest_version', '') if name and not public and 'conda' in package_types: if name in private_packages: versions = private_packages.get('versions', []), new_versions = item.get('versions', []), vers = sort_versions(list(set(versions + new_versions))) private_packages[name]['versions'] = vers private_packages[name]['latest_version'] = vers[-1] else: private_packages[name] = { 'versions': item.get('versions', []), 'app_entry': {}, 'type': {}, 'size': {}, 'latest_version': latest_version, } return private_packages
def get_package_versions(self, name, versiononly=True): """ Gives all the compatible package canonical name name : str name of the package versiononly : bool if `True`, returns version number only, otherwise canonical name """ versions = self._packages_versions if name in versions: if versiononly: ver = versions[name] temp = [] for ve in ver: n, v, b = conda_api_q.CondaProcess.split_canonical_name(ve) temp.append(v) return sort_versions(list(set(temp))) else: return versions[name] else: return []
def _multi_packages(self, logins=None, platform=None, package_type=None, type_=None, access=None, new_client=True): """Return the private packages for a given set of usernames/logins.""" private_packages = {} if not new_client: time.sleep(0.3) return private_packages for login in logins: data = self._anaconda_client_api.user_packages( login=login, platform=platform, package_type=package_type, type_=type_, access=access) for item in data: name = item.get('name', '') public = item.get('public', True) package_types = item.get('package_types', []) latest_version = item.get('latest_version', '') if name and not public and 'conda' in package_types: if name in private_packages: versions = private_packages.get('versions', []), new_versions = item.get('versions', []), vers = sort_versions(list(set(versions + new_versions))) private_packages[name]['versions'] = vers private_packages[name]['latest_version'] = vers[-1] else: private_packages[name] = { 'versions': item.get('versions', []), 'app_entry': {}, 'type': {}, 'size': {}, 'latest_version': latest_version, } return private_packages
def _prepare_model_data(self, packages, linked, pip=[], private_packages={}): """ """ data = [] if private_packages is not None: for pkg in private_packages: if pkg in packages: p_data = packages.get(pkg, None) versions = p_data.get('versions', '') if p_data else [] private_versions = private_packages[pkg]['versions'] all_versions = sort_versions(list(set(versions + private_versions))) packages[pkg]['versions'] = all_versions else: private_versions = sort_versions(private_packages[pkg]['versions']) private_packages[pkg]['versions'] = private_versions packages[pkg] = private_packages[pkg] else: private_packages = {} linked_packages = {} for canonical_name in linked: name, version, b = tuple(canonical_name.rsplit('-', 2)) linked_packages[name] = {'version': version} pip_packages = {} for canonical_name in pip: name, version, b = tuple(canonical_name.rsplit('-', 2)) pip_packages[name] = {'version': version} packages_names = sorted(list(set(list(linked_packages.keys()) + list(pip_packages.keys()) + list(packages.keys()) + list(private_packages.keys()) ) ) ) for name in packages_names: p_data = packages.get(name, None) summary = p_data.get('summary', '') if p_data else '' url = p_data.get('home', '') if p_data else '' license_ = p_data.get('license', '') if p_data else '' versions = p_data.get('versions', '') if p_data else [] version = p_data.get('latest_version', '') if p_data else '' if name in pip_packages: type_ = C.PIP_PACKAGE version = pip_packages[name].get('version', '') status = C.INSTALLED elif name in linked_packages: type_ = C.CONDA_PACKAGE version = linked_packages[name].get('version', '') status = C.INSTALLED if version in versions: vers = versions upgradable = not version == vers[-1] and len(vers) != 1 downgradable = not version == vers[0] and len(vers) != 1 if upgradable and downgradable: status = C.MIXGRADABLE elif upgradable: status = C.UPGRADABLE elif downgradable: status = C.DOWNGRADABLE else: type_ = C.CONDA_PACKAGE status = C.NOT_INSTALLED if version == '' and len(versions) != 0: version = versions[-1] row = {C.COL_ACTION: C.ACTION_NONE, C.COL_PACKAGE_TYPE: type_, C.COL_NAME: name, C.COL_DESCRIPTION: summary.capitalize(), C.COL_VERSION: version, C.COL_STATUS: status, C.COL_URL: url, C.COL_LICENSE: license_, C.COL_INSTALL: False, C.COL_REMOVE: False, C.COL_UPGRADE: False, C.COL_DOWNGRADE: False, C.COL_ACTION_VERSION: None } data.append(row) return data
def _load_repodata(self, filepaths, extra_data={}, metadata={}): """ Load all the available pacakges information for downloaded repodata files (repo.continuum.io), additional data provided (anaconda cloud), and additional metadata and merge into a single set of packages and apps. """ repodata = [] for filepath in filepaths: compressed = filepath.endswith('.bz2') mode = 'rb' if filepath.endswith('.bz2') else 'r' if os.path.isfile(filepath): with open(filepath, mode) as f: raw_data = f.read() if compressed: data = bz2.decompress(raw_data) else: data = raw_data try: data = json.loads(to_text_string(data, 'UTF-8')) except Exception as error: logger.error(str(error)) data = {} repodata.append(data) all_packages = {} for data in repodata: packages = data.get('packages', {}) for canonical_name in packages: data = packages[canonical_name] name, version, b = tuple(canonical_name.rsplit('-', 2)) if name not in all_packages: all_packages[name] = {'versions': set(), 'size': {}, 'type': {}, 'app_entry': {}, 'app_type': {}, } elif name in metadata: temp_data = all_packages[name] temp_data['home'] = metadata[name].get('home', '') temp_data['license'] = metadata[name].get('license', '') temp_data['summary'] = metadata[name].get('summary', '') temp_data['latest_version'] = metadata[name].get('version') all_packages[name] = temp_data all_packages[name]['versions'].add(version) all_packages[name]['size'][version] = data.get('size', '') # Only the latest builds will have the correct metadata for # apps, so only store apps that have the app metadata if data.get('type', None): all_packages[name]['type'][version] = data.get( 'type', None) all_packages[name]['app_entry'][version] = data.get( 'app_entry', None) all_packages[name]['app_type'][version] = data.get( 'app_type', None) all_apps = {} for name in all_packages: versions = sort_versions(list(all_packages[name]['versions'])) all_packages[name]['versions'] = versions[:] for version in versions: has_type = all_packages[name].get('type', None) # Has type in this case implies being an app if has_type: all_apps[name] = all_packages[name].copy() # Remove all versions that are not apps! versions = all_apps[name]['versions'][:] types = all_apps[name]['type'] app_versions = [v for v in versions if v in types] all_apps[name]['versions'] = app_versions return all_packages, all_apps
def _prepare_model_data(self, packages, linked, pip=[], private_packages={}): """ """ data = [] if private_packages is not None: for pkg in private_packages: if pkg in packages: p_data = packages.get(pkg, None) versions = p_data.get('versions', '') if p_data else [] private_versions = private_packages[pkg]['versions'] all_versions = sort_versions( list(set(versions + private_versions))) packages[pkg]['versions'] = all_versions else: private_versions = sort_versions( private_packages[pkg]['versions']) private_packages[pkg]['versions'] = private_versions packages[pkg] = private_packages[pkg] else: private_packages = {} linked_packages = {} for canonical_name in linked: name, version, b = tuple(canonical_name.rsplit('-', 2)) linked_packages[name] = {'version': version} pip_packages = {} for canonical_name in pip: name, version, b = tuple(canonical_name.rsplit('-', 2)) pip_packages[name] = {'version': version} packages_names = sorted( list( set( list(linked_packages.keys()) + list(pip_packages.keys()) + list(packages.keys()) + list(private_packages.keys())))) for name in packages_names: p_data = packages.get(name, None) summary = p_data.get('summary', '') if p_data else '' url = p_data.get('home', '') if p_data else '' license_ = p_data.get('license', '') if p_data else '' versions = p_data.get('versions', '') if p_data else [] version = p_data.get('latest_version', '') if p_data else '' if name in pip_packages: type_ = C.PIP_PACKAGE version = pip_packages[name].get('version', '') status = C.INSTALLED elif name in linked_packages: type_ = C.CONDA_PACKAGE version = linked_packages[name].get('version', '') status = C.INSTALLED if version in versions: vers = versions upgradable = not version == vers[-1] and len(vers) != 1 downgradable = not version == vers[0] and len(vers) != 1 if upgradable and downgradable: status = C.MIXGRADABLE elif upgradable: status = C.UPGRADABLE elif downgradable: status = C.DOWNGRADABLE else: type_ = C.CONDA_PACKAGE status = C.NOT_INSTALLED if version == '' and len(versions) != 0: version = versions[-1] row = { C.COL_ACTION: C.ACTION_NONE, C.COL_PACKAGE_TYPE: type_, C.COL_NAME: name, C.COL_DESCRIPTION: summary.capitalize(), C.COL_VERSION: version, C.COL_STATUS: status, C.COL_URL: url, C.COL_LICENSE: license_, C.COL_INSTALL: False, C.COL_REMOVE: False, C.COL_UPGRADE: False, C.COL_DOWNGRADE: False, C.COL_ACTION_VERSION: None } data.append(row) return data
def _load_repodata(self, filepaths, extra_data={}, metadata={}): """ Load all the available pacakges information for downloaded repodata files (repo.continuum.io), additional data provided (anaconda cloud), and additional metadata and merge into a single set of packages and apps. """ repodata = [] for filepath in filepaths: compressed = filepath.endswith('.bz2') mode = 'rb' if filepath.endswith('.bz2') else 'r' if os.path.isfile(filepath): with open(filepath, mode) as f: raw_data = f.read() if compressed: data = bz2.decompress(raw_data) else: data = raw_data try: data = json.loads(to_text_string(data, 'UTF-8')) except Exception as error: logger.error(str(error)) data = {} repodata.append(data) all_packages = {} for data in repodata: packages = data.get('packages', {}) for canonical_name in packages: data = packages[canonical_name] name, version, b = tuple(canonical_name.rsplit('-', 2)) if name not in all_packages: all_packages[name] = { 'versions': set(), 'size': {}, 'type': {}, 'app_entry': {}, 'app_type': {}, } elif name in metadata: temp_data = all_packages[name] temp_data['home'] = metadata[name].get('home', '') temp_data['license'] = metadata[name].get('license', '') temp_data['summary'] = metadata[name].get('summary', '') temp_data['latest_version'] = metadata[name].get('version') all_packages[name] = temp_data all_packages[name]['versions'].add(version) all_packages[name]['size'][version] = data.get('size', '') # Only the latest builds will have the correct metadata for # apps, so only store apps that have the app metadata if data.get('type', None): all_packages[name]['type'][version] = data.get( 'type', None) all_packages[name]['app_entry'][version] = data.get( 'app_entry', None) all_packages[name]['app_type'][version] = data.get( 'app_type', None) all_apps = {} for name in all_packages: versions = sort_versions(list(all_packages[name]['versions'])) all_packages[name]['versions'] = versions[:] for version in versions: has_type = all_packages[name].get('type', None) # Has type in this case implies being an app if has_type: all_apps[name] = all_packages[name].copy() # Remove all versions that are not apps! versions = all_apps[name]['versions'][:] types = all_apps[name]['type'] app_versions = [v for v in versions if v in types] all_apps[name]['versions'] = app_versions return all_packages, all_apps
def _setup_data(self): """ """ self._packages_names = [] self._rows = [] self._packages_versions = {} # the canonical name of versions compat self._packages_linked = {} self._packages_versions_number = {} self._packages_versions_all = {} # the canonical name of all versions self._packages_upgradable = {} self._packages_downgradable = {} self._packages_installable = {} self._packages_licenses_all = {} self._conda_api = conda_api_q.CondaProcess cp = self._conda_api # TODO: Do we want to exclude some packages? If we plan to continue # with the projects in spyder idea, we might as well hide spyder # from the possible instalable apps... # exclude_names = ['emptydummypackage'] # FIXME: packages to exclude? # First do the list of linked packages so in case there is no json # We can show at least that self._packages_linked = {} # FIXME: move this logic outside...? canonical_names = sorted(list(cp.linked(self._prefix))) # This has to do with the versions of the selected environment, NOT # with the python version running! pyver, numpyver, pybuild, numpybuild = None, None, None, None for canonical_name in canonical_names: n, v, b = cp.split_canonical_name(canonical_name) self._packages_linked[n] = [n, v, b, canonical_name] if n == 'python': pyver = v pybuild = b elif n == 'numpy': numpyver = v numpybuild = b if self._packages == {}: self._packages_names = sorted([l for l in self._packages_linked]) self._rows = list(range(len(self._packages_names))) for n in self._packages_linked: val = self._packages_linked[n] v = val[-1] self._packages[n] = [[v, v]] else: self._packages_names = sorted([key for key in self._packages]) self._rows = list(range(len(self._packages_names))) for n in self._packages: self._packages_licenses_all[n] = {} pybuild = 'py' + ''.join(pyver.split('.')[:-1]) + '_' # + pybuild if numpyver is None and numpybuild is None: numpybuild = '' else: numpybuild = 'np' + ''.join(numpyver.split('.'))[:-1] for n in self._packages_names: self._packages_versions_all[n] = \ sort_versions([s[0] for s in self._packages[n]], reverse=True) for s in self._packages[n]: val = s[1] if 'version' in val: ver = val['version'] if 'license' in val: lic = val['license'] self._packages_licenses_all[n][ver] = lic # Now clean versions depending on the build version of python and numpy # FIXME: there is an issue here... at this moment a package with same # version but only differing in the build number will get added # Now it assumes that there is a python installed in the root for name in self._packages_versions_all: tempver_cano = [] tempver_num = [] for ver in self._packages_versions_all[name]: n, v, b = cp.split_canonical_name(ver) if 'np' in b and 'py' in b: if numpybuild + pybuild in b: tempver_cano.append(ver) tempver_num.append(v) elif 'py' in b: if pybuild in b: tempver_cano.append(ver) tempver_num.append(v) elif 'np' in b: if numpybuild in b: tempver_cano.append(ver) tempver_num.append(v) else: tempver_cano.append(ver) tempver_num.append(v) self._packages_versions[name] = sort_versions(tempver_cano, reverse=True) self._packages_versions_number[name] = sort_versions(tempver_num, reverse=True) # FIXME: Check what to do with different builds?? # For the moment here a set is used to remove duplicate versions for n in self._packages_linked: vals = self._packages_linked[n] canonical_name = vals[-1] current_ver = vals[1] # fix error when package installed from other channels besides # the standard ones if n in self._packages_versions_number: vers = self._packages_versions_number[n] vers = sort_versions(list(set(vers)), reverse=True) # If no other version is available just give a dummy version if not vers: vers = [-1] self._packages_upgradable[n] = not current_ver == vers[0] self._packages_downgradable[n] = not current_ver == vers[-1] for row, name in enumerate(self._packages_names): if name in self._packages_linked: version = self._packages_linked[name][1] if (self._packages_upgradable[name] and self._packages_downgradable[name]): status = const.MIXGRADABLE elif self._packages_upgradable[name]: status = const.UPGRADABLE elif self._packages_downgradable[name]: status = const.DOWNGRADABLE else: status = const.INSTALLED else: vers = self._packages_versions_number[name] vers = sort_versions(list(set(vers)), reverse=True) version = '-' if len(vers) == 0: status = const.NOT_INSTALLABLE else: status = const.NOT_INSTALLED metadata = self._get_package_metadata(name) description = metadata['description'] url = metadata['url'] if version in self._packages_licenses_all[name]: if self._packages_licenses_all[name][version]: license_ = self._packages_licenses_all[name][version] else: license_ = u'' else: license_ = u'' # TODO: Temporal fix to include pip packages if name in self._pip_packages_names: type_ = const.PIP status = const.INSTALLED version = self._pip_packages_names[name]['version'] else: type_ = const.CONDA self._rows[row] = [type_, name, description, version, status, url, license_, False, False, False, False] self.row_data = self._rows self.packages_names = self._packages_names self.packages_versions = self._packages_versions self.sig_ready.emit()
def __init__(self, parent, prefix, name, action, version, versions): super(CondaPackageActionDialog, self).__init__(parent) self._parent = parent self._prefix = prefix self._version_text = None self._name = name self._dependencies_dic = {} self._conda_process = conda_api_q.CondaProcess(self) # Widgets self.label = QLabel(self) self.combobox_version = QComboBox() self.label_version = QLabel(self) self.widget_version = None self.table_dependencies = None self.checkbox = QCheckBox(_('Install dependencies (recommended)')) self.bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) self.button_ok = self.bbox.button(QDialogButtonBox.Ok) self.button_cancel = self.bbox.button(QDialogButtonBox.Cancel) self.button_cancel.setDefault(True) self.button_cancel.setAutoDefault(True) dialog_size = QSize(300, 90) # Helper variable values action_title = {const.UPGRADE: _("Upgrade package"), const.DOWNGRADE: _("Downgrade package"), const.REMOVE: _("Remove package"), const.INSTALL: _("Install package")} # Versions might have duplicates from different builds versions = sort_versions(list(set(versions)), reverse=True) # FIXME: There is a bug, a package installed by anaconda has version # astropy 0.4 and the linked list 0.4 but the available versions # in the json file do not include 0.4 but 0.4rc1... so... # temporal fix is to check if inside list otherwise show full list if action == const.UPGRADE: if version in versions: index = versions.index(version) versions = versions[:index] else: versions = versions elif action == const.DOWNGRADE: if version in versions: index = versions.index(version) versions = versions[index+1:] else: versions = versions elif action == const.REMOVE: versions = [version] self.combobox_version.setEnabled(False) if len(versions) == 1: if action == const.REMOVE: labeltext = _('Package version to remove:') else: labeltext = _('Package version available:') self.label_version.setText(versions[0]) self.widget_version = self.label_version else: labeltext = _("Select package version:") self.combobox_version.addItems(versions) self.widget_version = self.combobox_version self.label.setText(labeltext) self.label_version.setAlignment(Qt.AlignLeft) self.table_dependencies = QWidget(self) self._layout = QGridLayout() self._layout.addWidget(self.label, 0, 0, Qt.AlignVCenter | Qt.AlignLeft) self._layout.addWidget(self.widget_version, 0, 1, Qt.AlignVCenter | Qt.AlignRight) self.widgets = [self.checkbox, self.button_ok, self.widget_version, self.table_dependencies] row_index = 1 # Create a Table if action in [const.INSTALL, const.UPGRADE, const.DOWNGRADE]: table = QTableView(self) dialog_size = QSize(dialog_size.width() + 40, 300) self.table_dependencies = table row_index = 1 self._layout.addItem(QSpacerItem(10, 5), row_index, 0) self._layout.addWidget(self.checkbox, row_index + 1, 0, 1, 2) self.checkbox.setChecked(True) self._changed_version(versions[0]) table.setSelectionBehavior(QAbstractItemView.SelectRows) table.verticalHeader().hide() table.horizontalHeader().hide() table.setAlternatingRowColors(True) table.setShowGrid(False) table.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) table.horizontalHeader().setStretchLastSection(True) self._layout.addWidget(self.table_dependencies, row_index + 2, 0, 1, 2, Qt.AlignHCenter) self._layout.addItem(QSpacerItem(10, 5), row_index + 3, 0) self._layout.addWidget(self.bbox, row_index + 6, 0, 1, 2, Qt.AlignHCenter) title = "{0}: {1}".format(action_title[action], name) self.setLayout(self._layout) self.setMinimumSize(dialog_size) self.setFixedSize(dialog_size) self.setWindowTitle(title) self.setModal(True) # Signals and slots self.bbox.accepted.connect(self.accept) self.bbox.rejected.connect(self.close) self.combobox_version.currentIndexChanged.connect( self._changed_version) self.checkbox.stateChanged.connect(self._changed_checkbox) self._conda_process.sig_finished.connect(self._on_process_finished)