| 1 |  |  | # -*- coding: utf-8 -*- | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  | # ----------------------------------------------------------------------------- | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | # Copyright © 2015- The Spyder Development Team | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  | # Copyright © 2014-2015 Gonzalo Peña-Castellanos (@goanpeca) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | # Licensed under the terms of the MIT License | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | # ----------------------------------------------------------------------------- | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | """API for using the api (anaconda-client, downloads and conda).""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | # Standard library imports | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  | import json | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  | import os | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  | import tempfile | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  | # Third party imports | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  | from qtpy.QtCore import QObject, Signal | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 17 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 18 |  |  | # Local imports | 
            
                                                                        
                            
            
                                    
            
            
                | 19 |  |  | from conda_manager.api.client_api import ClientAPI | 
            
                                                                        
                            
            
                                    
            
            
                | 20 |  |  | from conda_manager.api.conda_api import CondaAPI | 
            
                                                                        
                            
            
                                    
            
            
                | 21 |  |  | from conda_manager.api.download_api import DownloadAPI, RequestsDownloadAPI | 
            
                                                                        
                            
            
                                    
            
            
                | 22 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 23 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 24 |  |  | class _ManagerAPI(QObject): | 
            
                                                                        
                            
            
                                    
            
            
                | 25 |  |  |     """Anaconda Manager API process worker.""" | 
            
                                                                        
                            
            
                                    
            
            
                | 26 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 27 |  |  |     sig_repodata_updated = Signal(object) | 
            
                                                                        
                            
            
                                    
            
            
                | 28 |  |  |     sig_repodata_errored = Signal() | 
            
                                                                        
                            
            
                                    
            
            
                | 29 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 30 |  |  |     def __init__(self): | 
            
                                                                        
                            
            
                                    
            
            
                | 31 |  |  |         """Anaconda Manager API process worker.""" | 
            
                                                                        
                            
            
                                    
            
            
                | 32 |  |  |         super(_ManagerAPI, self).__init__() | 
            
                                                                        
                            
            
                                    
            
            
                | 33 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 34 |  |  |         # API's | 
            
                                                                        
                            
            
                                    
            
            
                | 35 |  |  |         self._conda_api = CondaAPI() | 
            
                                                                        
                            
            
                                    
            
            
                | 36 |  |  |         self._client_api = ClientAPI() | 
            
                                                                        
                            
            
                                    
            
            
                | 37 |  |  |         self._download_api = DownloadAPI(load_rc_func=self._conda_api.load_rc) | 
            
                                                                        
                            
            
                                    
            
            
                | 38 |  |  |         self._requests_download_api = RequestsDownloadAPI( | 
            
                                                                        
                            
            
                                    
            
            
                | 39 |  |  |             load_rc_func=self._conda_api.load_rc) | 
            
                                                                        
                            
            
                                    
            
            
                | 40 |  |  |         self.ROOT_PREFIX = self._conda_api.ROOT_PREFIX | 
            
                                                                        
                            
            
                                    
            
            
                | 41 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 42 |  |  |         # Vars | 
            
                                                                        
                            
            
                                    
            
            
                | 43 |  |  |         self._checking_repos = None | 
            
                                                                        
                            
            
                                    
            
            
                | 44 |  |  |         self._data_directory = None | 
            
                                                                        
                            
            
                                    
            
            
                | 45 |  |  |         self._files_downloaded = None | 
            
                                                                        
                            
            
                                    
            
            
                | 46 |  |  |         self._repodata_files = None | 
            
                                                                        
                            
            
                                    
            
            
                | 47 |  |  |         self._valid_repos = None | 
            
                                                                        
                            
            
                                    
            
            
                | 48 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 49 |  |  |         # Expose some methods for convenient access. Methods return a worker | 
            
                                                                        
                            
            
                                    
            
            
                | 50 |  |  |         self.conda_create = self._conda_api.create | 
            
                                                                        
                            
            
                                    
            
            
                | 51 |  |  |         self.conda_create_yaml = self._conda_api.create_from_yaml | 
            
                                                                        
                            
            
                                    
            
            
                | 52 |  |  |         self.conda_clone = self._conda_api.clone_environment | 
            
                                                                        
                            
            
                                    
            
            
                | 53 |  |  |         self.conda_dependencies = self._conda_api.dependencies | 
            
                                                                        
                            
            
                                    
            
            
                | 54 |  |  |         self.conda_get_condarc_channels = self._conda_api.get_condarc_channels | 
            
                                                                        
                            
            
                                    
            
            
                | 55 |  |  |         self.conda_install = self._conda_api.install | 
            
                                                                        
                            
            
                                    
            
            
                | 56 |  |  |         self.conda_remove = self._conda_api.remove | 
            
                                                                        
                            
            
                                    
            
            
                | 57 |  |  |         self.conda_terminate = self._conda_api.terminate_all_processes | 
            
                                                                        
                            
            
                                    
            
            
                | 58 |  |  |         self.conda_config_add = self._conda_api.config_add | 
            
                                                                        
                            
            
                                    
            
            
                | 59 |  |  |         self.conda_config_remove = self._conda_api.config_remove | 
            
                                                                        
                            
            
                                    
            
            
                | 60 |  |  |         self.pip_list = self._conda_api.pip_list | 
            
                                                                        
                            
            
                                    
            
            
                | 61 |  |  |         self.pip_remove = self._conda_api.pip_remove | 
            
                                                                        
                            
            
                                    
            
            
                | 62 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 63 |  |  |         # No workers are returned for these methods | 
            
                                                                        
                            
            
                                    
            
            
                | 64 |  |  |         self.conda_clear_lock = self._conda_api.clear_lock | 
            
                                                                        
                            
            
                                    
            
            
                | 65 |  |  |         self.conda_environment_exists = self._conda_api.environment_exists | 
            
                                                                        
                            
            
                                    
            
            
                | 66 |  |  |         self.conda_get_envs = self._conda_api.get_envs | 
            
                                                                        
                            
            
                                    
            
            
                | 67 |  |  |         self.conda_linked = self._conda_api.linked | 
            
                                                                        
                            
            
                                    
            
            
                | 68 |  |  |         self.conda_get_prefix_envname = self._conda_api.get_prefix_envname | 
            
                                                                        
                            
            
                                    
            
            
                | 69 |  |  |         self.conda_package_version = self._conda_api.package_version | 
            
                                                                        
                            
            
                                    
            
            
                | 70 |  |  |         self.conda_platform = self._conda_api.get_platform | 
            
                                                                        
                            
            
                                    
            
            
                | 71 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 72 |  |  |         # These download methods return a worker | 
            
                                                                        
                            
            
                                    
            
            
                | 73 |  |  |         get_api_info = self._requests_download_api.get_api_info | 
            
                                                                        
                            
            
                                    
            
            
                | 74 |  |  |         is_valid_url = self._requests_download_api.is_valid_api_url | 
            
                                                                        
                            
            
                                    
            
            
                | 75 |  |  |         is_valid_channel = self._requests_download_api.is_valid_channel | 
            
                                                                        
                            
            
                                    
            
            
                | 76 |  |  |         terminate = self._requests_download_api.terminate | 
            
                                                                        
                            
            
                                    
            
            
                | 77 |  |  |         self.download_requests = self._requests_download_api.download | 
            
                                                                        
                            
            
                                    
            
            
                | 78 |  |  |         self.download_async = self._download_api.download | 
            
                                                                        
                            
            
                                    
            
            
                | 79 |  |  |         self.download_async_terminate = self._download_api.terminate | 
            
                                                                        
                            
            
                                    
            
            
                | 80 |  |  |         self.download_is_valid_url = self._requests_download_api.is_valid_url | 
            
                                                                        
                            
            
                                    
            
            
                | 81 |  |  |         self.download_is_valid_api_url = is_valid_url | 
            
                                                                        
                            
            
                                    
            
            
                | 82 |  |  |         self.download_get_api_info = lambda: get_api_info( | 
            
                                                                        
                            
            
                                    
            
            
                | 83 |  |  |             self._client_api.get_api_url()) | 
            
                                                                        
                            
            
                                    
            
            
                | 84 |  |  |         self.download_is_valid_channel = is_valid_channel | 
            
                                                                        
                            
            
                                    
            
            
                | 85 |  |  |         self.download_requests_terminate = terminate | 
            
                                                                        
                            
            
                                    
            
            
                | 86 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 87 |  |  |         # These client methods return a worker | 
            
                                                                        
                            
            
                                    
            
            
                | 88 |  |  |         self.client_store_token = self._client_api.store_token | 
            
                                                                        
                            
            
                                    
            
            
                | 89 |  |  |         self.client_remove_token = self._client_api.remove_token | 
            
                                                                        
                            
            
                                    
            
            
                | 90 |  |  |         self.client_login = self._client_api.login | 
            
                                                                        
                            
            
                                    
            
            
                | 91 |  |  |         self.client_logout = self._client_api.logout | 
            
                                                                        
                            
            
                                    
            
            
                | 92 |  |  |         self.client_load_repodata = self._client_api.load_repodata | 
            
                                                                        
                            
            
                                    
            
            
                | 93 |  |  |         self.client_prepare_packages_data = self._client_api.prepare_model_data | 
            
                                                                        
                            
            
                                    
            
            
                | 94 |  |  |         self.client_user = self._client_api.user | 
            
                                                                        
                            
            
                                    
            
            
                | 95 |  |  |         self.client_domain = self._client_api.domain | 
            
                                                                        
                            
            
                                    
            
            
                | 96 |  |  |         self.client_set_domain = self._client_api.set_domain | 
            
                                                                        
                            
            
                                    
            
            
                | 97 |  |  |         self.client_packages = self._client_api.packages | 
            
                                                                        
                            
            
                                    
            
            
                | 98 |  |  |         self.client_multi_packages = self._client_api.multi_packages | 
            
                                                                        
                            
            
                                    
            
            
                | 99 |  |  |         self.client_organizations = self._client_api.organizations | 
            
                                                                        
                            
            
                                    
            
            
                | 100 |  |  |         self.client_load_token = self._client_api.load_token | 
            
                                                                        
                            
            
                                    
            
            
                | 101 |  |  |         self.client_get_api_url = self._client_api.get_api_url | 
            
                                                                        
                            
            
                                    
            
            
                | 102 |  |  |         self.client_set_api_url = self._client_api.set_api_url | 
            
                                                                        
                            
            
                                    
            
            
                | 103 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 104 |  |  |     # --- Helper methods | 
            
                                                                        
                            
            
                                    
            
            
                | 105 |  |  |     # ------------------------------------------------------------------------- | 
            
                                                                        
                            
            
                                    
            
            
                | 106 |  |  |     def _set_repo_urls_from_channels(self, channels): | 
            
                                                                        
                            
            
                                    
            
            
                | 107 |  |  |         """ | 
            
                                                                        
                            
            
                                    
            
            
                | 108 |  |  |         Convert a channel into a normalized repo name including. | 
            
                                                                        
                            
            
                                    
            
            
                | 109 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 110 |  |  |         Channels are assumed in normalized url form. | 
            
                                                                        
                            
            
                                    
            
            
                | 111 |  |  |         """ | 
            
                                                                        
                            
            
                                    
            
            
                | 112 |  |  |         repos = [] | 
            
                                                                        
                            
            
                                    
            
            
                | 113 |  |  |         sys_platform = self._conda_api.get_platform() | 
            
                                                                        
                            
            
                                    
            
            
                | 114 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 115 |  |  |         for channel in channels: | 
            
                                                                        
                            
            
                                    
            
            
                | 116 |  |  |             url = '{0}/{1}/repodata.json.bz2'.format(channel, sys_platform) | 
            
                                                                        
                            
            
                                    
            
            
                | 117 |  |  |             repos.append(url) | 
            
                                                                        
                            
            
                                    
            
            
                | 118 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 119 |  |  |         return repos | 
            
                                                                        
                            
            
                                    
            
            
                | 120 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 121 |  |  |     def _check_repos(self, repos): | 
            
                                                                        
                            
            
                                    
            
            
                | 122 |  |  |         """Check if repodata urls are valid.""" | 
            
                                                                        
                            
            
                                    
            
            
                | 123 |  |  |         self._checking_repos = [] | 
            
                                                                        
                            
            
                                    
            
            
                | 124 |  |  |         self._valid_repos = [] | 
            
                                                                        
                            
            
                                    
            
            
                | 125 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 126 |  |  |         for repo in repos: | 
            
                                                                        
                            
            
                                    
            
            
                | 127 |  |  |             worker = self.download_is_valid_url(repo) | 
            
                                                                        
                            
            
                                    
            
            
                | 128 |  |  |             worker.sig_finished.connect(self._repos_checked) | 
            
                                                                        
                            
            
                                    
            
            
                | 129 |  |  |             worker.repo = repo | 
            
                                                                        
                            
            
                                    
            
            
                | 130 |  |  |             self._checking_repos.append(repo) | 
            
                                                                        
                            
            
                                    
            
            
                | 131 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 132 |  |  |     def _repos_checked(self, worker, output, error): | 
            
                                                                        
                            
            
                                    
            
            
                | 133 |  |  |         """Callback for _check_repos.""" | 
            
                                                                        
                            
            
                                    
            
            
                | 134 |  |  |         if worker.repo in self._checking_repos: | 
            
                                                                        
                            
            
                                    
            
            
                | 135 |  |  |             self._checking_repos.remove(worker.repo) | 
            
                                                                        
                            
            
                                    
            
            
                | 136 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 137 |  |  |         if output: | 
            
                                                                        
                            
            
                                    
            
            
                | 138 |  |  |             self._valid_repos.append(worker.repo) | 
            
                                                                        
                            
            
                                    
            
            
                | 139 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 140 |  |  |         if len(self._checking_repos) == 0: | 
            
                                                                        
                            
            
                                    
            
            
                | 141 |  |  |             self._download_repodata(self._valid_repos) | 
            
                                                                        
                            
            
                                    
            
            
                | 142 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 143 |  |  |     def _repo_url_to_path(self, repo): | 
            
                                                                        
                            
            
                                    
            
            
                | 144 |  |  |         """Convert a `repo` url to a file path for local storage.""" | 
            
                                                                        
                            
            
                                    
            
            
                | 145 |  |  |         repo = repo.replace('http://', '') | 
            
                                                                        
                            
            
                                    
            
            
                | 146 |  |  |         repo = repo.replace('https://', '') | 
            
                                                                        
                            
            
                                    
            
            
                | 147 |  |  |         repo = repo.replace('/', '_') | 
            
                                                                        
                            
            
                                    
            
            
                | 148 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 149 |  |  |         return os.sep.join([self._data_directory, repo]) | 
            
                                                                        
                            
            
                                    
            
            
                | 150 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 151 |  |  |     def _download_repodata(self, checked_repos): | 
            
                                                                        
                            
            
                                    
            
            
                | 152 |  |  |         """Dowload repodata.""" | 
            
                                                                        
                            
            
                                    
            
            
                | 153 |  |  |         self._files_downloaded = [] | 
            
                                                                        
                            
            
                                    
            
            
                | 154 |  |  |         self._repodata_files = [] | 
            
                                                                        
                            
            
                                    
            
            
                | 155 |  |  |         self.__counter = -1 | 
            
                                                                        
                            
            
                                    
            
            
                | 156 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 157 |  |  |         if checked_repos: | 
            
                                                                        
                            
            
                                    
            
            
                | 158 |  |  |             for repo in checked_repos: | 
            
                                                                        
                            
            
                                    
            
            
                | 159 |  |  |                 path = self._repo_url_to_path(repo) | 
            
                                                                        
                            
            
                                    
            
            
                | 160 |  |  |                 self._files_downloaded.append(path) | 
            
                                                                        
                            
            
                                    
            
            
                | 161 |  |  |                 self._repodata_files.append(path) | 
            
                                                                        
                            
            
                                    
            
            
                | 162 |  |  |                 worker = self.download_async(repo, path) | 
            
                                                                        
                            
            
                                    
            
            
                | 163 |  |  |                 worker.url = repo | 
            
                                                                        
                            
            
                                    
            
            
                | 164 |  |  |                 worker.path = path | 
            
                                                                        
                            
            
                                    
            
            
                | 165 |  |  |                 worker.sig_finished.connect(self._repodata_downloaded) | 
            
                                                                        
                            
            
                                    
            
            
                | 166 |  |  |         else: | 
            
                                                                        
                            
            
                                    
            
            
                | 167 |  |  |             # Empty, maybe there is no internet connection | 
            
                                                                        
                            
            
                                    
            
            
                | 168 |  |  |             # Load information from conda-meta and save that file | 
            
                                                                        
                            
            
                                    
            
            
                | 169 |  |  |             path = self._get_repodata_from_meta() | 
            
                                                                        
                            
            
                                    
            
            
                | 170 |  |  |             self._repodata_files = [path] | 
            
                                                                        
                            
            
                                    
            
            
                | 171 |  |  |             self._repodata_downloaded() | 
            
                                                                        
                            
            
                                    
            
            
                | 172 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 173 |  |  |     def _get_repodata_from_meta(self): | 
            
                                                                        
                            
            
                                    
            
            
                | 174 |  |  |         """Generate repodata from local meta files.""" | 
            
                                                                        
                            
            
                                    
            
            
                | 175 |  |  |         path = os.sep.join([self.ROOT_PREFIX, 'conda-meta']) | 
            
                                                                        
                            
            
                                    
            
            
                | 176 |  |  |         packages = os.listdir(path) | 
            
                                                                        
                            
            
                                    
            
            
                | 177 |  |  |         meta_repodata = {} | 
            
                                                                        
                            
            
                                    
            
            
                | 178 |  |  |         for pkg in packages: | 
            
                                                                        
                            
            
                                    
            
            
                | 179 |  |  |             if pkg.endswith('.json'): | 
            
                                                                        
                            
            
                                    
            
            
                | 180 |  |  |                 filepath = os.sep.join([path, pkg]) | 
            
                                                                        
                            
            
                                    
            
            
                | 181 |  |  |                 with open(filepath, 'r') as f: | 
            
                                                                        
                            
            
                                    
            
            
                | 182 |  |  |                     data = json.load(f) | 
            
                                                                        
                            
            
                                    
            
            
                | 183 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 184 |  |  |                 if 'files' in data: | 
            
                                                                        
                            
            
                                    
            
            
                | 185 |  |  |                     data.pop('files') | 
            
                                                                        
                            
            
                                    
            
            
                | 186 |  |  |                 if 'icondata' in data: | 
            
                                                                        
                            
            
                                    
            
            
                | 187 |  |  |                     data.pop('icondata') | 
            
                                                                        
                            
            
                                    
            
            
                | 188 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 189 |  |  |                 name = pkg.replace('.json', '') | 
            
                                                                        
                            
            
                                    
            
            
                | 190 |  |  |                 meta_repodata[name] = data | 
            
                                                                        
                            
            
                                    
            
            
                | 191 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 192 |  |  |         meta_repodata_path = os.sep.join([self._data_directory, | 
            
                                                                        
                            
            
                                    
            
            
                | 193 |  |  |                                           'offline.json']) | 
            
                                                                        
                            
            
                                    
            
            
                | 194 |  |  |         repodata = {'info': [], | 
            
                                                                        
                            
            
                                    
            
            
                | 195 |  |  |                     'packages': meta_repodata} | 
            
                                                                        
                            
            
                                    
            
            
                | 196 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 197 |  |  |         with open(meta_repodata_path, 'w') as f: | 
            
                                                                        
                            
            
                                    
            
            
                | 198 |  |  |             json.dump(repodata, f, sort_keys=True, | 
            
                                                                        
                            
            
                                    
            
            
                | 199 |  |  |                       indent=4, separators=(',', ': ')) | 
            
                                                                        
                            
            
                                    
            
            
                | 200 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 201 |  |  |         return meta_repodata_path | 
            
                                                                        
                            
            
                                    
            
            
                | 202 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 203 |  |  |     def _repodata_downloaded(self, worker=None, output=None, error=None): | 
            
                                                                        
                            
            
                                    
            
            
                | 204 |  |  |         """Callback for _download_repodata.""" | 
            
                                                                        
                            
            
                                    
            
            
                | 205 |  |  |         if worker: | 
            
                                                                        
                            
            
                                    
            
            
                | 206 |  |  |             self._files_downloaded.remove(worker.path) | 
            
                                                                        
                            
            
                                    
            
            
                | 207 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 208 |  |  |             if worker.path in self._files_downloaded: | 
            
                                                                        
                            
            
                                    
            
            
                | 209 |  |  |                 self._files_downloaded.remove(worker.path) | 
            
                                                                        
                            
            
                                    
            
            
                | 210 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 211 |  |  |         if len(self._files_downloaded) == 0: | 
            
                                                                        
                            
            
                                    
            
            
                | 212 |  |  |             self.sig_repodata_updated.emit(list(set(self._repodata_files))) | 
            
                                                                        
                            
            
                                    
            
            
                | 213 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 214 |  |  |     # --- Public API | 
            
                                                                        
                            
            
                                    
            
            
                | 215 |  |  |     # ------------------------------------------------------------------------- | 
            
                                                                        
                            
            
                                    
            
            
                | 216 |  |  |     def repodata_files(self, channels=None): | 
            
                                                                        
                            
            
                                    
            
            
                | 217 |  |  |         """ | 
            
                                                                        
                            
            
                                    
            
            
                | 218 |  |  |         Return the repodata paths based on `channels` and the `data_directory`. | 
            
                                                                        
                            
            
                                    
            
            
                | 219 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 220 |  |  |         There is no check for validity here. | 
            
                                                                        
                            
            
                                    
            
            
                | 221 |  |  |         """ | 
            
                                                                        
                            
            
                                    
            
            
                | 222 |  |  |         if channels is None: | 
            
                                                                        
                            
            
                                    
            
            
                | 223 |  |  |             channels = self.conda_get_condarc_channels() | 
            
                                                                        
                            
            
                                    
            
            
                | 224 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 225 |  |  |         repodata_urls = self._set_repo_urls_from_channels(channels) | 
            
                                                                        
                            
            
                                    
            
            
                | 226 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 227 |  |  |         repopaths = [] | 
            
                                                                        
                            
            
                                    
            
            
                | 228 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 229 |  |  |         for repourl in repodata_urls: | 
            
                                                                        
                            
            
                                    
            
            
                | 230 |  |  |             fullpath = os.sep.join([self._repo_url_to_path(repourl)]) | 
            
                                                                        
                            
            
                                    
            
            
                | 231 |  |  |             repopaths.append(fullpath) | 
            
                                                                        
                            
            
                                    
            
            
                | 232 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 233 |  |  |         return repopaths | 
            
                                                                        
                            
            
                                    
            
            
                | 234 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 235 |  |  |     def set_data_directory(self, data_directory): | 
            
                                                                        
                            
            
                                    
            
            
                | 236 |  |  |         """Set the directory where repodata and metadata are stored.""" | 
            
                                                                        
                            
            
                                    
            
            
                | 237 |  |  |         self._data_directory = data_directory | 
            
                                                                        
                            
            
                                    
            
            
                | 238 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 239 |  |  |     def update_repodata(self, channels=None): | 
            
                                                                        
                            
            
                                    
            
            
                | 240 |  |  |         """Update repodata from channels or use condarc channels if None.""" | 
            
                                                                        
                            
            
                                    
            
            
                | 241 |  |  |         norm_channels = self.conda_get_condarc_channels(channels=channels, | 
            
                                                                        
                            
            
                                    
            
            
                | 242 |  |  |                                                         normalize=True) | 
            
                                                                        
                            
            
                                    
            
            
                | 243 |  |  |         repodata_urls = self._set_repo_urls_from_channels(norm_channels) | 
            
                                                                        
                            
            
                                    
            
            
                | 244 |  |  |         self._check_repos(repodata_urls) | 
            
                                                                        
                            
            
                                    
            
            
                | 245 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 246 |  |  |     def update_metadata(self): | 
            
                                                                        
                            
            
                                    
            
            
                | 247 |  |  |         """ | 
            
                                                                        
                            
            
                                    
            
            
                | 248 |  |  |         Update the metadata available for packages in repo.continuum.io. | 
            
                                                                        
                            
            
                                    
            
            
                | 249 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 250 |  |  |         Returns a download worker. | 
            
                                                                        
                            
            
                                    
            
            
                | 251 |  |  |         """ | 
            
                                                                        
                            
            
                                    
            
            
                | 252 |  |  |         if self._data_directory is None: | 
            
                                                                        
                            
            
                                    
            
            
                | 253 |  |  |             raise Exception('Need to call `api.set_data_directory` first.') | 
            
                                                                        
                            
            
                                    
            
            
                | 254 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 255 |  |  |         metadata_url = 'https://repo.continuum.io/pkgs/metadata.json' | 
            
                                                                        
                            
            
                                    
            
            
                | 256 |  |  |         filepath = os.sep.join([self._data_directory, 'metadata.json']) | 
            
                                                                        
                            
            
                                    
            
            
                | 257 |  |  |         worker = self.download_requests(metadata_url, filepath) | 
            
                                                                        
                            
            
                                    
            
            
                | 258 |  |  |         return worker | 
            
                                                                        
                            
            
                                    
            
            
                | 259 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 260 |  |  |     def check_valid_channel(self, | 
            
                                                                        
                            
            
                                    
            
            
                | 261 |  |  |                             channel, | 
            
                                                                        
                            
            
                                    
            
            
                | 262 |  |  |                             conda_url='https://conda.anaconda.org'): | 
            
                                                                        
                            
            
                                    
            
            
                | 263 |  |  |         """Check if channel is valid.""" | 
            
                                                                        
                            
            
                                    
            
            
                | 264 |  |  |         if channel.startswith('https://') or channel.startswith('http://'): | 
            
                                                                        
                            
            
                                    
            
            
                | 265 |  |  |             url = channel | 
            
                                                                        
                            
            
                                    
            
            
                | 266 |  |  |         else: | 
            
                                                                        
                            
            
                                    
            
            
                | 267 |  |  |             url = "{0}/{1}".format(conda_url, channel) | 
            
                                                                        
                            
            
                                    
            
            
                | 268 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 269 |  |  |         if url[-1] == '/': | 
            
                                                                        
                            
            
                                    
            
            
                | 270 |  |  |             url = url[:-1] | 
            
                                                                        
                            
            
                                    
            
            
                | 271 |  |  |         plat = self.conda_platform() | 
            
                                                                        
                            
            
                                    
            
            
                | 272 |  |  |         repodata_url = "{0}/{1}/{2}".format(url, plat, 'repodata.json') | 
            
                                                                        
                            
            
                                    
            
            
                | 273 |  |  |         worker = self.download_is_valid_url(repodata_url) | 
            
                                                                        
                            
            
                                    
            
            
                | 274 |  |  |         worker.url = url | 
            
                                                                        
                            
            
                                    
            
            
                | 275 |  |  |         return worker | 
            
                                                                        
                            
            
                                    
            
            
                | 276 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 277 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 278 |  |  | MANAGER_API = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 279 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 280 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 281 |  |  | def ManagerAPI(): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 282 |  |  |     """Manager API threaded worker.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 283 |  |  |     global MANAGER_API | 
            
                                                                                                            
                            
            
                                    
            
            
                | 284 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 285 |  |  |     if MANAGER_API is None: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 286 |  |  |         MANAGER_API = _ManagerAPI() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 287 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 288 |  |  |     return MANAGER_API | 
            
                                                                                                            
                            
            
                                    
            
            
                | 289 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 290 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 291 |  |  | # --- Local testing | 
            
                                                                                                            
                            
            
                                    
            
            
                | 292 |  |  | # ----------------------------------------------------------------------------- | 
            
                                                                                                            
                            
            
                                    
            
            
                | 293 |  |  | def finished(worker, output, error):  # pragma: no cover | 
            
                                                                                                            
                            
            
                                    
            
            
                | 294 |  |  |     """Print information on test finished.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 295 |  |  |     print(worker, output, error) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 296 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 297 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 298 |  |  | def download_finished(url, path):  # pragma: no cover | 
            
                                                                                                            
                            
            
                                    
            
            
                | 299 |  |  |     """Print information on downlaod finished.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 300 |  |  |     print(url, path) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 301 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 302 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 303 |  |  | def repodata_updated(repos):  # pragma: no cover | 
            
                                                                                                            
                            
            
                                    
            
            
                | 304 |  |  |     """Print information on repodata updated.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 305 |  |  |     print(repos) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 306 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 307 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 308 |  |  | def test():  # pragma: no cover | 
            
                                                                                                            
                            
            
                                    
            
            
                | 309 |  |  |     """Main local test.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 310 |  |  |     from conda_manager.utils.qthelpers import qapplication | 
            
                                                                                                            
                            
            
                                    
            
            
                | 311 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 312 |  |  |     app = qapplication() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 313 |  |  |     api = ManagerAPI() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 314 |  |  |     api.sig_repodata_updated.connect(repodata_updated) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 315 |  |  |     data_directory = tempfile.mkdtemp() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 316 |  |  |     api.set_data_directory(data_directory) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 317 |  |  |     worker = api.update_metadata() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 318 |  |  |     worker.sig_download_finished.connect(download_finished) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 319 |  |  |     api.update_repodata() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 320 |  |  |     app.exec_() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 321 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 322 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 323 |  |  | if __name__ == '__main__':  # pragma: no cover | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 324 |  |  |     test() | 
            
                                                        
            
                                    
            
            
                | 325 |  |  |  |