def py_in_console(activate=None, prog='python'): """ Run (i)python in a new console. It optionally run activate first on the given env name/path. """ logger.debug("%s, %s", activate, prog) if not check_prog(prog, activate): raise RuntimeError( 'Program not available in environment: %s, %s', prog, activate ) if prog == 'python': cmd = 'python -i' elif prog == 'ipython': cmd = 'ipython -i' elif 'notebook' in prog: cmd = 'jupyter notebook' from anaconda_navigator.api.conda_api import CONDA_API # Jupyter notebook shouldn't be launched from a console launch(activate, cmd, True, root_prefix=CONDA_API.ROOT_PREFIX) return else: cmd = None console(activate=activate, term_command=cmd)
def login(self): """ Open up login dialog or log out depending on logged status. """ if self.logged: QApplication.setOverrideCursor(Qt.WaitCursor) self.api.client_logout() self.api.client_remove_token() self.logged = False self.sig_logged_out.emit() self.tracker.track_event('authenticate', 'logout', label=self.username) else: dlg = AuthenticationDialog(self.api, parent=self) if self.tracker: self.tracker.track_page('/login', pagetitle='Login dialog') if dlg.exec_(): self.api.client_store_token(dlg.token) self.username = dlg.username self.logged = True self.sig_logged_in.emit() if self.tracker: self.tracker.track_event('authenticate', 'login', label=self.username) self._track_tab() self.update_login_status() logger.debug(str((self.logged, self.username)))
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 launch( prefix, command, leave_path_alone, working_directory=os.path.expanduser('~'), package_name=None, root_prefix=None, environment=None, non_conda=False, as_admin=False, ): """Handle launching commands from projects.""" logger.debug(str((prefix, command))) prefix = prefix.replace('\\', '/') root_prefix = root_prefix.replace('\\', '/') new_command = command.replace('\\', '/') pid = -1 # if os.name == 'nt' and not leave_path_alone: # command = command.replace('/bin', '/Scripts') if MAC or LINUX: popen_dict = get_command_on_unix( prefix=prefix, command=new_command, package_name=package_name, root_prefix=root_prefix, environment=environment, non_conda=non_conda, cwd=working_directory, ) else: popen_dict = get_command_on_win( prefix=prefix, command=new_command, package_name=package_name, root_prefix=root_prefix, environment=environment, non_conda=non_conda, cwd=working_directory, ) # args here is the temporary file that gets generated to carry # out activation args = popen_dict.pop('args') id_ = popen_dict.pop('id') cmd = popen_dict.pop('cmd') cmd # dummy usage for linter if WIN: if as_admin: p = run_as_admin(args) else: p = subprocess.Popen(args, **popen_dict).pid else: p = subprocess.Popen('sh {}'.format(args), **popen_dict).pid return p, id_
def is_enterprise_license(cls, lic): """Check if a license is of enterprise type.""" if not LICENSE_PACKAGE: return False logger.debug(lic) return not cls.is_trial_license(lic)
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 load_repodata(self, repodata, metadata=None, python_version=None): """ Load all the available packages information for downloaded repodata. 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. If python_version is not none, exclude all package/versions which require an incompatible version of python. Parameters ---------- repodata: dict of dicts Data loaded from the conda cache directories. metadata: dict Metadata info form different sources. For now only from repo.continuum. python_version: str Python version used in preprocessing. """ logger.debug('') method = self._load_repodata return self._create_worker( method, repodata, metadata=metadata, python_version=python_version, )
def is_expired_license(cls, lic): """Check if the license is expired.""" if not LICENSE_PACKAGE: return True logger.debug(lic) return cls.get_days_left(lic) == 0
def run_ex(*args): """ Start new console window, run command (given as string list). """ logger.debug(str(args)) cmd = '{0}'.format(" ".join(args)) if os.name == 'nt': subprocess.Popen(['start', 'cmd.exe', '/K', cmd]) elif sys.platform == 'darwin': fname = 'a.tool' open(fname, 'w').write(cmd) os.chmod(fname, 0o777) subprocess.call(['open ' + fname], shell=True) os.unlink(fname) else: terms = ['gnome-terminal', 'konsole', 'xterm'] for term in terms: try: subprocess.Popen([term, '-e', '"{}"'.format(cmd)]) break except Exception: pass
def logout(self): """ Logout from anaconda.org. This method removes the authentication and removes the token. """ error = None args = Args() args.site = None args.token = self.token binstar_client.utils.remove_token(args) if self.token: try: self._anaconda_client_api.remove_authentication() except binstar_client.errors.Unauthorized as e: error = e logger.debug("The token that you are trying to remove may " "not be valid {}".format(e)) except Exception as e: error = e logger.debug("The certificate might be invalid. {}".format(e)) logger.info("logout successful") return error
def make_tag_filters(self): """Create tag filtering checkboxes based on available content tags.""" if not self.tags: self.tags = set() for content_item in self.content_info: tags = content_item.get('tags', []) for tag in tags: if tag: self.tags.add(tag) # Get count tag_count = {tag: 0 for tag in self.tags} for tag in self.tags: for content_item in self.content_info: item_tags = content_item.get('tags', []) if tag in item_tags: tag_count[tag] += 1 logger.debug("TAGS: {0}".format(self.tags)) self.filter_widgets = [] for tag in sorted(self.tags): count = tag_count[tag] tag_text = "{0} ({1})".format(tag.capitalize(), count).strip() item = ButtonToggle(tag_text) item.setObjectName(tag.lower()) item.setChecked(self.config.get('checkboxes', tag.lower(), True)) item.clicked.connect(self.filter_content) self.filter_widgets.append(item) self.filters_layout.addWidget(item) self.filters_layout.addWidget(SpacerHorizontal())
def install_application(self, value=None, version=None): """ Update the application on the defined prefix environment. This is used for both normal install and specific version install. """ if version: self.version = version else: self.version = self.versions[-1] version = self.versions[-1] pkg = '{0}={1}'.format(self.name, version) pkgs = [pkg] logger.debug(str((pkg, self.dev_tool))) # Check if environment exists and then create or install # is_installed = self.api.conda_package_version(prefix=self.prefix, # pkg=self.name) # pkgs = [pkg] + self.BASIC_PACKAGES # if is_installed: # worker = self.api.conda_install(prefix=self.prefix, pkgs=pkgs) # else: # worker = self.api.conda_create(prefix=self.prefix, pkgs=pkgs) worker = self.api.conda_install(prefix=self.prefix, pkgs=pkgs) worker.sig_finished.connect(self._application_installed) worker.sig_partial.connect(self._partial_output_ready) self.set_loading(True) self.widget.sig_status_updated.emit('Installing application ' '<b>{0}</b>'.format(self.name))
def load_icon(self, project_path, project=None, as_pixmap=False): """ Load project icon for project located at `project_path`. """ logger.debug(str((project_path, project['name'], as_pixmap))) from PIL.ImageQt import ImageQt from PIL import Image if project is None: project = self.load_project(project_path) icon_path = os.sep.join([project_path, project.icon]) if os.path.isfile(icon_path): try: icon = qta.icon('fa.gear') image = Image.open(icon_path) image = ImageQt(image) qt_image = QImage(image) pixmap = QPixmap.fromImage(qt_image) icon = QIcon(pixmap) except Exception: icon = qta.icon('fa.gear') else: icon = qta.icon('fa.gear') if as_pixmap: try: icon = icon.pixmap(icon.availableSizes()[0]) except Exception: icon = QPixmap(*IMAGE_ICON_SIZE) return icon
def save_icon(self, image_path, project_path, project=None): """ Save a project icon based on a given image path. """ logger.debug(str((image_path, project_path, project))) from PIL.ImageQt import ImageQt from PIL import Image if project is None: project = self.load_project(project_path) if os.path.isfile(image_path): new_icon_path = os.sep.join([project_path, project.icon]) extension = image_path.split('.')[-1] with open(image_path, 'rb') as f: img = Image.open(f) img.thumbnail(IMAGE_ICON_SIZE) image = ImageQt(img) qt_image = QImage(image) if os.path.isfile(new_icon_path): os.remove(new_icon_path) try: qt_image.save(new_icon_path, format=extension) except Exception as err: print(err)
def set_domain(self, domain='https://api.anaconda.org'): """Reset current api domain.""" logger.debug('Setting domain {}'.format(domain)) config = binstar_client.utils.get_config() config['url'] = domain try: binstar_client.utils.set_config(config) except binstar_client.errors.BinstarError: logger.error('Could not write anaconda client configuation') traceback = format_exc() msg_box = MessageBoxError( title='Anaconda Client configuration error', text='Anaconda Client domain could not be updated.<br><br>' 'This may result in Navigator not working properly.<br>', error='<pre>' + traceback + '</pre>', report=False, learn_more=None, ) msg_box.exec_() self._anaconda_client_api = binstar_client.utils.get_server_api( token=None, log_level=logging.NOTSET, )
def license_location(cls): """Return license main location.""" if not LICENSE_PACKAGE: return [] logger.debug('') return _license.get_license_dirs()[0]
def packages(self, login=None, platform=None, package_type=None, type_=None, access=None): """Return all the available packages for a given user. Parameters ---------- type_: Optional[str] Only find packages that have this conda `type`, (i.e. 'app'). access : Optional[str] Only find packages that have this access level (e.g. 'private', 'authenticated', 'public'). """ logger.debug('') method = self._anaconda_client_api.user_packages return self._create_worker( method, login=login, platform=platform, package_type=package_type, type_=type_, access=access, )
def is_trial_license(cls, lic): """Check if a license is of trial type.""" if not LICENSE_PACKAGE: return True logger.debug(lic) return lic.get('type', '').lower() == 'trial'
def launch( prefix, command, leave_path_alone, working_directory=HOME_PATH, package_name=None, root_prefix=None, ): """Handle launching commands from projects.""" logger.debug(str((prefix, command))) command = command.replace('\\', '/') prefix = prefix.replace('\\', '/') root_prefix = root_prefix.replace('\\', '/') pid = -1 if os.name == 'nt' and not leave_path_alone: command = command.replace('/bin', '/Scripts') if MAC or LINUX: pid = run_app_on_unix(prefix=prefix, command=command, package_name=package_name, root_prefix=root_prefix) else: pid = run_app_on_win(prefix=prefix, command=command, package_name=package_name, root_prefix=root_prefix) return pid
def load_licenses(cls, product=None): """Load license files.""" logger.debug(product) res = [] # This is used instead of _license.find_licenses to have the path # for each file for license_path in cls.license_paths(): try: licenses = _license.read_licenses(license_path) except Exception: logger.warning( "Can't read licenses from folder {0}".format(license_path)) licenses = [] for lic in licenses: product_name = lic.get('product') product_filter = product == product_name if product else True if product_name in VALID_PRODUCT_LICENSES and product_filter: valid = cls.is_valid_license(lic) lic['__valid__'] = valid lic['__status__'] = 'Valid' if valid else 'Invalid' lic['__type__'] = lic.get('type', 'Enterprise').lower() lic[LICENSE_PATH] = license_path res.append(lic) return res
def add_project(self, path=None, dev_tool_only=False): """ Add (import) a new project located on a path. Path must contain a valid `project.yaml`. """ logger.debug(str((path, dev_tool_only)))
def get_projects(paths=None): """Return an ordered dictionary of all existing projects on paths.""" logger.debug(paths) projects = OrderedDict() if paths and None not in paths: project_paths = [] if paths and isinstance(paths, (list, tuple)): for path in paths: project_paths.extend([ os.path.join(path, i) for i in os.listdir(path) if os.path.isdir(os.path.join(path, i)) ]) for project_path in project_paths: files = [] # See https://github.com/ContinuumIO/navigator/issues/1207 try: files = os.listdir(project_path) except Exception: pass if 'anaconda-project.yml' in files: projects[project_path] = os.path.basename(project_path) return projects
def add_license(self, paths): """Add license file callback.""" logger.debug(paths) valid_licenses = {} invalid_licenses = {} paths = [p for p in paths if os.path.isfile(p)] for path in paths: lic = _license.read_licenses(path) if lic: valid_licenses[path] = lic else: invalid_licenses[path] = None # FIXME: Check if license name exists in any of the paths # And then ask the user a question based on this if not os.path.isdir(self.license_location()): os.mkdir(self.license_location()) for path in valid_licenses: head, tail = os.path.split(path) new_path = os.path.join(self.license_location(), tail) with open(new_path, 'w') as f: json.dump(valid_licenses[path], f) return valid_licenses, invalid_licenses
def _process_conda_info(info): """Process conda info output and add some extra keys.""" logger.debug('info: {}'.format(info)) processed_info = info.copy() # Add a key for writable environment directories envs_dirs_writable = [] for env_dir in info['envs_dirs']: if path_is_writable(env_dir): envs_dirs_writable.append(env_dir) processed_info['__envs_dirs_writable'] = envs_dirs_writable # Add a key for writable environment directories pkgs_dirs_writable = [] for pkg_dir in info['pkgs_dirs']: if path_is_writable(pkg_dir): pkgs_dirs_writable.append(pkg_dir) processed_info['__pkgs_dirs_writable'] = pkgs_dirs_writable # Add a key for all environments root_prefix = info['root_prefix'] environments = OrderedDict() environments[root_prefix] = 'root' envs = info['envs'] envs_names = [os.path.basename(env) for env in envs] for env_name, env_prefix in sorted(zip(envs_names, envs)): environments[env_prefix] = env_name processed_info['__environments'] = environments return processed_info
def load_bundled_metadata(self): """Load bundled metadata.""" logger.debug('') comp_meta_filepath = content.BUNDLE_METADATA_COMP_PATH conf_meta_filepath = content.CONF_METADATA_PATH conf_meta_folder = METADATA_PATH if not os.path.isdir(conf_meta_folder): try: os.makedirs(conf_meta_folder) except Exception: pass binary_data = None if comp_meta_filepath and os.path.isfile(comp_meta_filepath): with open(comp_meta_filepath, 'rb') as f: binary_data = f.read() if binary_data: try: data = bz2.decompress(binary_data) with open(conf_meta_filepath, 'wb') as f: f.write(data) self._metadata = json.loads(data) except Exception as e: print(e) self._metadata = {}
def _config_sources(worker, output, error): logger.debug('output: {}, error: {}'.format(output, error)) base_worker = worker worker = self._conda_api.config_show(prefix=prefix) worker.config_sources = output worker.base_worker = base_worker worker.sig_finished.connect(_config)
def conda_config_and_sources(self, prefix=None): """Show config and config sources for a given prefix.""" logger.debug('prefix: {}'.format(prefix)) def _config_sources(worker, output, error): logger.debug('output: {}, error: {}'.format(output, error)) base_worker = worker worker = self._conda_api.config_show(prefix=prefix) worker.config_sources = output worker.base_worker = base_worker worker.sig_finished.connect(_config) def _config(worker, output, error): logger.debug('output: {}, error: {}'.format(output, error)) base_worker = worker.base_worker config_sources = worker.config_sources config = output new_output = { 'config': config, 'config_sources': config_sources, } base_worker.sig_chain_finished.emit(base_worker, new_output, error) worker = self._conda_api.config_show_sources(prefix=prefix) worker.sig_finished.connect(_config_sources) return worker
def api_urls(self): """Get all the api urls for the current api url.""" logger.debug('') api_url = self._client_api.get_api_url() def _config(worker, output, error): logger.debug('output: {}, error: {}'.format(output, error)) base_worker = worker proxy_servers = output.get('proxy_servers', {}) verify = output.get('ssl_verify ', True) worker = self._client_api.get_api_info( api_url, proxy_servers=proxy_servers, verify=verify, ) worker.base_worker = base_worker worker.sig_finished.connect(_api_info) def _api_info(worker, output, error): logger.debug('output: {}, error: {}'.format(output, error)) base_worker = worker.base_worker base_worker.sig_chain_finished.emit(base_worker, output, error) worker = self._conda_api.config_show() worker.sig_finished.connect(_config) return worker
def _config_sources(worker, config_sources, error): logger.debug('config_sources: {}, error: {}'.format( config_sources, error)) base_worker = worker.base_worker worker = self._conda_api.config_show(prefix=prefix) base_worker.config_sources = config_sources worker.base_worker = base_worker worker.sig_finished.connect(_config)
def logout(self): """ Logout from anaconda cloud via the anaconda-client API. This method does not use workers. """ logger.debug('') return self._client_api.logout()