| 
									
										
										
										
											2017-06-05 16:02:39 +03:00
										 |  |  | # Copyright (c) 2014-present PlatformIO <contact@platformio.org> | 
					
						
							| 
									
										
										
										
											2015-11-18 17:16:17 +02:00
										 |  |  | # | 
					
						
							|  |  |  | # Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  | # you may not use this file except in compliance with the License. | 
					
						
							|  |  |  | # You may obtain a copy of the License at | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #    http://www.apache.org/licenses/LICENSE-2.0 | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  | # distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  | # See the License for the specific language governing permissions and | 
					
						
							|  |  |  | # limitations under the License. | 
					
						
							| 
									
										
										
										
											2014-09-03 23:03:49 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 15:55:08 +02:00
										 |  |  | # pylint: disable=too-many-branches, too-many-locals | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-30 17:59:06 +03:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2018-01-16 00:57:06 +02:00
										 |  |  | import time | 
					
						
							| 
									
										
										
										
											2015-01-05 22:58:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-24 22:18:19 +03:00
										 |  |  | import click | 
					
						
							| 
									
										
										
										
											2019-05-24 14:09:25 +03:00
										 |  |  | import semantic_version | 
					
						
							| 
									
										
										
										
											2019-08-17 20:55:16 +03:00
										 |  |  | from tabulate import tabulate | 
					
						
							| 
									
										
										
										
											2014-09-04 18:58:12 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-29 23:08:08 +02:00
										 |  |  | from platformio import exception, fs, util | 
					
						
							| 
									
										
										
										
											2019-07-03 15:10:37 +03:00
										 |  |  | from platformio.commands import PlatformioCLI | 
					
						
							| 
									
										
										
										
											2019-06-05 17:57:22 +03:00
										 |  |  | from platformio.compat import dump_json_to_unicode | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  | from platformio.managers.lib import LibraryManager, get_builtin_libs, is_builtin_lib | 
					
						
							| 
									
										
										
										
											2019-10-01 00:11:31 +03:00
										 |  |  | from platformio.package.manifest.parser import ManifestParserFactory | 
					
						
							| 
									
										
										
										
											2019-12-29 13:13:04 +02:00
										 |  |  | from platformio.package.manifest.schema import ManifestSchema | 
					
						
							| 
									
										
										
										
											2019-05-16 21:03:15 +03:00
										 |  |  | from platformio.proc import is_ci | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  | from platformio.project.config import ProjectConfig | 
					
						
							| 
									
										
										
										
											2020-03-27 13:34:14 +02:00
										 |  |  | from platformio.project.exception import InvalidProjectConfError | 
					
						
							| 
									
										
										
										
											2019-09-27 14:13:53 +03:00
										 |  |  | from platformio.project.helpers import get_project_dir, is_platformio_project | 
					
						
							| 
									
										
										
										
											2014-09-03 23:03:49 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-26 20:54:29 +02:00
										 |  |  | try: | 
					
						
							|  |  |  |     from urllib.parse import quote | 
					
						
							|  |  |  | except ImportError: | 
					
						
							|  |  |  |     from urllib import quote | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-23 19:39:04 +03:00
										 |  |  | CTX_META_INPUT_DIRS_KEY = __name__ + ".input_dirs" | 
					
						
							|  |  |  | CTX_META_PROJECT_ENVIRONMENTS_KEY = __name__ + ".project_environments" | 
					
						
							| 
									
										
										
										
											2019-05-23 13:05:44 +03:00
										 |  |  | CTX_META_STORAGE_DIRS_KEY = __name__ + ".storage_dirs" | 
					
						
							| 
									
										
										
										
											2019-05-23 18:37:08 +03:00
										 |  |  | CTX_META_STORAGE_LIBDEPS_KEY = __name__ + ".storage_lib_deps" | 
					
						
							| 
									
										
										
										
											2019-05-23 13:05:44 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-27 14:13:53 +03:00
										 |  |  | def get_project_global_lib_dir(): | 
					
						
							|  |  |  |     return ProjectConfig.get_instance().get_optional_dir("globallib") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  | @click.group(short_help="Library Manager") | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  | @click.option( | 
					
						
							|  |  |  |     "-d", | 
					
						
							|  |  |  |     "--storage-dir", | 
					
						
							|  |  |  |     multiple=True, | 
					
						
							|  |  |  |     default=None, | 
					
						
							|  |  |  |     type=click.Path( | 
					
						
							|  |  |  |         exists=True, file_okay=False, dir_okay=True, writable=True, resolve_path=True | 
					
						
							|  |  |  |     ), | 
					
						
							|  |  |  |     help="Manage custom library storage", | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | @click.option( | 
					
						
							|  |  |  |     "-g", "--global", is_flag=True, help="Manage global PlatformIO library storage" | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  | @click.option( | 
					
						
							|  |  |  |     "-e", | 
					
						
							|  |  |  |     "--environment", | 
					
						
							|  |  |  |     multiple=True, | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |     help=( | 
					
						
							|  |  |  |         "Manage libraries for the specific project build environments " | 
					
						
							|  |  |  |         "declared in `platformio.ini`" | 
					
						
							|  |  |  |     ), | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  | @click.pass_context | 
					
						
							|  |  |  | def cli(ctx, **options): | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  |     storage_cmds = ("install", "uninstall", "update", "list") | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  |     # skip commands that don't need storage folder | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |     if ctx.invoked_subcommand not in storage_cmds or ( | 
					
						
							|  |  |  |         len(ctx.args) == 2 and ctx.args[1] in ("-h", "--help") | 
					
						
							|  |  |  |     ): | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |     storage_dirs = list(options["storage_dir"]) | 
					
						
							|  |  |  |     if options["global"]: | 
					
						
							| 
									
										
										
										
											2019-05-24 20:49:05 +03:00
										 |  |  |         storage_dirs.append(get_project_global_lib_dir()) | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  |     if not storage_dirs: | 
					
						
							|  |  |  |         if is_platformio_project(): | 
					
						
							|  |  |  |             storage_dirs = [get_project_dir()] | 
					
						
							| 
									
										
										
										
											2019-05-16 21:03:15 +03:00
										 |  |  |         elif is_ci(): | 
					
						
							| 
									
										
										
										
											2019-05-24 20:49:05 +03:00
										 |  |  |             storage_dirs = [get_project_global_lib_dir()] | 
					
						
							| 
									
										
										
										
											2016-09-01 01:30:14 +03:00
										 |  |  |             click.secho( | 
					
						
							|  |  |  |                 "Warning! Global library storage is used automatically. " | 
					
						
							|  |  |  |                 "Please use `platformio lib --global %s` command to remove " | 
					
						
							|  |  |  |                 "this warning." % ctx.invoked_subcommand, | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |                 fg="yellow", | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  |     if not storage_dirs: | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         raise exception.NotGlobalLibDir( | 
					
						
							|  |  |  |             get_project_dir(), get_project_global_lib_dir(), ctx.invoked_subcommand | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-05-23 13:05:44 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-03 15:10:37 +03:00
										 |  |  |     in_silence = PlatformioCLI.in_silence() | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |     ctx.meta[CTX_META_PROJECT_ENVIRONMENTS_KEY] = options["environment"] | 
					
						
							| 
									
										
										
										
											2019-05-23 19:39:04 +03:00
										 |  |  |     ctx.meta[CTX_META_INPUT_DIRS_KEY] = storage_dirs | 
					
						
							| 
									
										
										
										
											2019-05-23 13:05:44 +03:00
										 |  |  |     ctx.meta[CTX_META_STORAGE_DIRS_KEY] = [] | 
					
						
							| 
									
										
										
										
											2019-05-23 18:37:08 +03:00
										 |  |  |     ctx.meta[CTX_META_STORAGE_LIBDEPS_KEY] = {} | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  |     for storage_dir in storage_dirs: | 
					
						
							| 
									
										
										
										
											2019-05-23 18:37:08 +03:00
										 |  |  |         if not is_platformio_project(storage_dir): | 
					
						
							| 
									
										
										
										
											2019-05-23 13:05:44 +03:00
										 |  |  |             ctx.meta[CTX_META_STORAGE_DIRS_KEY].append(storage_dir) | 
					
						
							| 
									
										
										
										
											2019-05-23 18:37:08 +03:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2020-02-29 23:08:08 +02:00
										 |  |  |         with fs.cd(storage_dir): | 
					
						
							|  |  |  |             config = ProjectConfig.get_instance( | 
					
						
							|  |  |  |                 os.path.join(storage_dir, "platformio.ini") | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |             ) | 
					
						
							| 
									
										
										
										
											2020-02-29 23:08:08 +02:00
										 |  |  |             config.validate(options["environment"], silent=in_silence) | 
					
						
							|  |  |  |             libdeps_dir = config.get_optional_dir("libdeps") | 
					
						
							|  |  |  |             for env in config.envs(): | 
					
						
							|  |  |  |                 if options["environment"] and env not in options["environment"]: | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 storage_dir = os.path.join(libdeps_dir, env) | 
					
						
							|  |  |  |                 ctx.meta[CTX_META_STORAGE_DIRS_KEY].append(storage_dir) | 
					
						
							|  |  |  |                 ctx.meta[CTX_META_STORAGE_LIBDEPS_KEY][storage_dir] = config.get( | 
					
						
							|  |  |  |                     "env:" + env, "lib_deps", [] | 
					
						
							|  |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @cli.command("install", short_help="Install library") | 
					
						
							|  |  |  | @click.argument("libraries", required=False, nargs=-1, metavar="[LIBRARY...]") | 
					
						
							| 
									
										
										
										
											2019-05-23 19:39:04 +03:00
										 |  |  | @click.option( | 
					
						
							|  |  |  |     "--save", | 
					
						
							|  |  |  |     is_flag=True, | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |     help="Save installed libraries into the `platformio.ini` dependency list", | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | @click.option("-s", "--silent", is_flag=True, help="Suppress progress reporting") | 
					
						
							|  |  |  | @click.option( | 
					
						
							|  |  |  |     "--interactive", is_flag=True, help="Allow to make a choice for all prompts" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | @click.option( | 
					
						
							|  |  |  |     "-f", "--force", is_flag=True, help="Reinstall/redownload library if exists" | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2019-05-23 13:05:44 +03:00
										 |  |  | @click.pass_context | 
					
						
							| 
									
										
										
										
											2019-05-23 19:39:04 +03:00
										 |  |  | def lib_install(  # pylint: disable=too-many-arguments | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |     ctx, libraries, save, silent, interactive, force | 
					
						
							|  |  |  | ): | 
					
						
							| 
									
										
										
										
											2019-05-23 13:05:44 +03:00
										 |  |  |     storage_dirs = ctx.meta[CTX_META_STORAGE_DIRS_KEY] | 
					
						
							| 
									
										
										
										
											2019-05-23 19:39:04 +03:00
										 |  |  |     storage_libdeps = ctx.meta.get(CTX_META_STORAGE_LIBDEPS_KEY, []) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-24 14:09:25 +03:00
										 |  |  |     installed_manifests = {} | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  |     for storage_dir in storage_dirs: | 
					
						
							| 
									
										
										
										
											2019-05-23 18:37:08 +03:00
										 |  |  |         if not silent and (libraries or storage_dir in storage_libdeps): | 
					
						
							|  |  |  |             print_storage_header(storage_dirs, storage_dir) | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  |         lm = LibraryManager(storage_dir) | 
					
						
							| 
									
										
										
										
											2019-05-23 18:37:08 +03:00
										 |  |  |         if libraries: | 
					
						
							|  |  |  |             for library in libraries: | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |                 pkg_dir = lm.install( | 
					
						
							|  |  |  |                     library, silent=silent, interactive=interactive, force=force | 
					
						
							|  |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2019-05-24 14:09:25 +03:00
										 |  |  |                 installed_manifests[library] = lm.load_manifest(pkg_dir) | 
					
						
							| 
									
										
										
										
											2019-05-23 18:37:08 +03:00
										 |  |  |         elif storage_dir in storage_libdeps: | 
					
						
							| 
									
										
										
										
											2019-06-06 00:13:04 +03:00
										 |  |  |             builtin_lib_storages = None | 
					
						
							| 
									
										
										
										
											2019-05-23 18:37:08 +03:00
										 |  |  |             for library in storage_libdeps[storage_dir]: | 
					
						
							|  |  |  |                 try: | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |                     pkg_dir = lm.install( | 
					
						
							|  |  |  |                         library, silent=silent, interactive=interactive, force=force | 
					
						
							|  |  |  |                     ) | 
					
						
							| 
									
										
										
										
											2019-05-24 14:09:25 +03:00
										 |  |  |                     installed_manifests[library] = lm.load_manifest(pkg_dir) | 
					
						
							| 
									
										
										
										
											2019-05-23 18:37:08 +03:00
										 |  |  |                 except exception.LibNotFound as e: | 
					
						
							| 
									
										
										
										
											2019-06-06 00:13:04 +03:00
										 |  |  |                     if builtin_lib_storages is None: | 
					
						
							|  |  |  |                         builtin_lib_storages = get_builtin_libs() | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |                     if not silent or not is_builtin_lib(builtin_lib_storages, library): | 
					
						
							| 
									
										
										
										
											2019-05-23 18:37:08 +03:00
										 |  |  |                         click.secho("Warning! %s" % e, fg="yellow") | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-24 14:09:25 +03:00
										 |  |  |     if not save or not libraries: | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     input_dirs = ctx.meta.get(CTX_META_INPUT_DIRS_KEY, []) | 
					
						
							|  |  |  |     project_environments = ctx.meta[CTX_META_PROJECT_ENVIRONMENTS_KEY] | 
					
						
							|  |  |  |     for input_dir in input_dirs: | 
					
						
							| 
									
										
										
										
											2019-09-30 17:59:06 +03:00
										 |  |  |         config = ProjectConfig.get_instance(os.path.join(input_dir, "platformio.ini")) | 
					
						
							| 
									
										
										
										
											2019-05-24 14:09:25 +03:00
										 |  |  |         config.validate(project_environments) | 
					
						
							|  |  |  |         for env in config.envs(): | 
					
						
							|  |  |  |             if project_environments and env not in project_environments: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             config.expand_interpolations = False | 
					
						
							| 
									
										
										
										
											2020-03-27 13:34:14 +02:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 lib_deps = config.get("env:" + env, "lib_deps") | 
					
						
							|  |  |  |             except InvalidProjectConfError: | 
					
						
							|  |  |  |                 lib_deps = [] | 
					
						
							| 
									
										
										
										
											2019-05-24 14:09:25 +03:00
										 |  |  |             for library in libraries: | 
					
						
							|  |  |  |                 if library in lib_deps: | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 manifest = installed_manifests[library] | 
					
						
							|  |  |  |                 try: | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |                     assert library.lower() == manifest["name"].lower() | 
					
						
							|  |  |  |                     assert semantic_version.Version(manifest["version"]) | 
					
						
							| 
									
										
										
										
											2019-05-24 14:09:25 +03:00
										 |  |  |                     lib_deps.append("{name}@^{version}".format(**manifest)) | 
					
						
							|  |  |  |                 except (AssertionError, ValueError): | 
					
						
							|  |  |  |                     lib_deps.append(library) | 
					
						
							|  |  |  |             config.set("env:" + env, "lib_deps", lib_deps) | 
					
						
							|  |  |  |             config.save() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | @cli.command("uninstall", short_help="Uninstall libraries") | 
					
						
							|  |  |  | @click.argument("libraries", nargs=-1, metavar="[LIBRARY...]") | 
					
						
							| 
									
										
										
										
											2019-05-23 13:05:44 +03:00
										 |  |  | @click.pass_context | 
					
						
							|  |  |  | def lib_uninstall(ctx, libraries): | 
					
						
							|  |  |  |     storage_dirs = ctx.meta[CTX_META_STORAGE_DIRS_KEY] | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  |     for storage_dir in storage_dirs: | 
					
						
							|  |  |  |         print_storage_header(storage_dirs, storage_dir) | 
					
						
							|  |  |  |         lm = LibraryManager(storage_dir) | 
					
						
							|  |  |  |         for library in libraries: | 
					
						
							|  |  |  |             lm.uninstall(library) | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @cli.command("update", short_help="Update installed libraries") | 
					
						
							|  |  |  | @click.argument("libraries", required=False, nargs=-1, metavar="[LIBRARY...]") | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  | @click.option( | 
					
						
							|  |  |  |     "-c", | 
					
						
							|  |  |  |     "--only-check", | 
					
						
							|  |  |  |     is_flag=True, | 
					
						
							|  |  |  |     help="DEPRECATED. Please use `--dry-run` instead", | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | @click.option( | 
					
						
							|  |  |  |     "--dry-run", is_flag=True, help="Do not update, only check for the new versions" | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2017-01-30 01:04:06 +02:00
										 |  |  | @click.option("--json-output", is_flag=True) | 
					
						
							| 
									
										
										
										
											2019-05-23 13:05:44 +03:00
										 |  |  | @click.pass_context | 
					
						
							|  |  |  | def lib_update(ctx, libraries, only_check, dry_run, json_output): | 
					
						
							|  |  |  |     storage_dirs = ctx.meta[CTX_META_STORAGE_DIRS_KEY] | 
					
						
							| 
									
										
										
										
											2019-05-16 20:02:45 +03:00
										 |  |  |     only_check = dry_run or only_check | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  |     json_result = {} | 
					
						
							|  |  |  |     for storage_dir in storage_dirs: | 
					
						
							|  |  |  |         if not json_output: | 
					
						
							|  |  |  |             print_storage_header(storage_dirs, storage_dir) | 
					
						
							|  |  |  |         lm = LibraryManager(storage_dir) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         _libraries = libraries | 
					
						
							|  |  |  |         if not _libraries: | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |             _libraries = [manifest["__pkg_dir"] for manifest in lm.get_installed()] | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if only_check and json_output: | 
					
						
							|  |  |  |             result = [] | 
					
						
							|  |  |  |             for library in _libraries: | 
					
						
							| 
									
										
										
										
											2019-09-30 17:59:06 +03:00
										 |  |  |                 pkg_dir = library if os.path.isdir(library) else None | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  |                 requirements = None | 
					
						
							|  |  |  |                 url = None | 
					
						
							|  |  |  |                 if not pkg_dir: | 
					
						
							|  |  |  |                     name, requirements, url = lm.parse_pkg_uri(library) | 
					
						
							|  |  |  |                     pkg_dir = lm.get_package_dir(name, requirements, url) | 
					
						
							|  |  |  |                 if not pkg_dir: | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 latest = lm.outdated(pkg_dir, requirements) | 
					
						
							|  |  |  |                 if not latest: | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 manifest = lm.load_manifest(pkg_dir) | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |                 manifest["versionLatest"] = latest | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  |                 result.append(manifest) | 
					
						
							|  |  |  |             json_result[storage_dir] = result | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             for library in _libraries: | 
					
						
							|  |  |  |                 lm.update(library, only_check=only_check) | 
					
						
							| 
									
										
										
										
											2019-05-16 20:02:45 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  |     if json_output: | 
					
						
							|  |  |  |         return click.echo( | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |             dump_json_to_unicode( | 
					
						
							|  |  |  |                 json_result[storage_dirs[0]] if len(storage_dirs) == 1 else json_result | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-15 22:16:37 +02:00
										 |  |  |     return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-31 20:05:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  | @cli.command("list", short_help="List installed libraries") | 
					
						
							|  |  |  | @click.option("--json-output", is_flag=True) | 
					
						
							| 
									
										
										
										
											2019-05-23 13:05:44 +03:00
										 |  |  | @click.pass_context | 
					
						
							|  |  |  | def lib_list(ctx, json_output): | 
					
						
							|  |  |  |     storage_dirs = ctx.meta[CTX_META_STORAGE_DIRS_KEY] | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  |     json_result = {} | 
					
						
							|  |  |  |     for storage_dir in storage_dirs: | 
					
						
							|  |  |  |         if not json_output: | 
					
						
							|  |  |  |             print_storage_header(storage_dirs, storage_dir) | 
					
						
							|  |  |  |         lm = LibraryManager(storage_dir) | 
					
						
							|  |  |  |         items = lm.get_installed() | 
					
						
							|  |  |  |         if json_output: | 
					
						
							|  |  |  |             json_result[storage_dir] = items | 
					
						
							| 
									
										
										
										
											2019-05-27 17:19:33 +03:00
										 |  |  |         elif items: | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |             for item in sorted(items, key=lambda i: i["name"]): | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  |                 print_lib_item(item) | 
					
						
							| 
									
										
										
										
											2016-12-29 01:31:44 +02:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2019-05-27 17:19:33 +03:00
										 |  |  |             click.echo("No items found") | 
					
						
							| 
									
										
										
										
											2016-12-29 01:31:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  |     if json_output: | 
					
						
							|  |  |  |         return click.echo( | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |             dump_json_to_unicode( | 
					
						
							|  |  |  |                 json_result[storage_dirs[0]] if len(storage_dirs) == 1 else json_result | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2017-03-08 17:24:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  |     return True | 
					
						
							| 
									
										
										
										
											2014-09-03 23:03:49 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 15:55:08 +02:00
										 |  |  | @cli.command("search", short_help="Search for a library") | 
					
						
							| 
									
										
										
										
											2016-08-26 11:46:59 +03:00
										 |  |  | @click.argument("query", required=False, nargs=-1) | 
					
						
							| 
									
										
										
										
											2016-04-24 00:01:42 +03:00
										 |  |  | @click.option("--json-output", is_flag=True) | 
					
						
							|  |  |  | @click.option("--page", type=click.INT, default=1) | 
					
						
							| 
									
										
										
										
											2018-02-15 02:00:12 +02:00
										 |  |  | @click.option("--id", multiple=True) | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  | @click.option("-n", "--name", multiple=True) | 
					
						
							| 
									
										
										
										
											2014-09-24 22:18:19 +03:00
										 |  |  | @click.option("-a", "--author", multiple=True) | 
					
						
							|  |  |  | @click.option("-k", "--keyword", multiple=True) | 
					
						
							| 
									
										
										
										
											2014-10-19 00:14:11 +03:00
										 |  |  | @click.option("-f", "--framework", multiple=True) | 
					
						
							|  |  |  | @click.option("-p", "--platform", multiple=True) | 
					
						
							| 
									
										
										
										
											2016-09-07 18:50:09 +03:00
										 |  |  | @click.option("-i", "--header", multiple=True) | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  | @click.option( | 
					
						
							|  |  |  |     "--noninteractive", | 
					
						
							|  |  |  |     is_flag=True, | 
					
						
							|  |  |  |     help="Do not prompt, automatically paginate with delay", | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2016-08-26 11:46:59 +03:00
										 |  |  | def lib_search(query, json_output, page, noninteractive, **filters): | 
					
						
							| 
									
										
										
										
											2014-11-24 21:59:25 +02:00
										 |  |  |     if not query: | 
					
						
							| 
									
										
										
										
											2015-12-14 00:05:33 +02:00
										 |  |  |         query = [] | 
					
						
							| 
									
										
										
										
											2015-12-14 00:46:17 +02:00
										 |  |  |     if not isinstance(query, list): | 
					
						
							|  |  |  |         query = list(query) | 
					
						
							| 
									
										
										
										
											2014-11-24 21:59:25 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-27 20:51:55 +03:00
										 |  |  |     for key, values in filters.items(): | 
					
						
							| 
									
										
										
										
											2014-09-06 12:12:13 +03:00
										 |  |  |         for value in values: | 
					
						
							| 
									
										
										
										
											2015-12-14 00:05:33 +02:00
										 |  |  |             query.append('%s:"%s"' % (key, value)) | 
					
						
							| 
									
										
										
										
											2014-09-06 12:12:13 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |     result = util.get_api_result( | 
					
						
							|  |  |  |         "/v2/lib/search", dict(query=" ".join(query), page=page), cache_valid="1d" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2016-04-24 00:01:42 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if json_output: | 
					
						
							| 
									
										
										
										
											2019-06-05 17:57:22 +03:00
										 |  |  |         click.echo(dump_json_to_unicode(result)) | 
					
						
							| 
									
										
										
										
											2016-04-24 00:01:42 +03:00
										 |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |     if result["total"] == 0: | 
					
						
							| 
									
										
										
										
											2014-12-16 23:45:00 +02:00
										 |  |  |         click.secho( | 
					
						
							|  |  |  |             "Nothing has been found by your request\n" | 
					
						
							|  |  |  |             "Try a less-specific search or use truncation (or wildcard) " | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  |             "operator", | 
					
						
							|  |  |  |             fg="yellow", | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |             nl=False, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2014-12-16 23:45:00 +02:00
										 |  |  |         click.secho(" *", fg="green") | 
					
						
							|  |  |  |         click.secho("For example: DS*, PCA*, DHT* and etc.\n", fg="yellow") | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         click.echo( | 
					
						
							| 
									
										
										
										
											2019-09-27 14:13:53 +03:00
										 |  |  |             "For more examples and advanced search syntax, please use documentation:" | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  |         click.secho( | 
					
						
							| 
									
										
										
										
											2018-08-15 19:44:02 +03:00
										 |  |  |             "https://docs.platformio.org/page/userguide/lib/cmd_search.html\n", | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |             fg="cyan", | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2014-12-16 23:45:00 +02:00
										 |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |     click.secho( | 
					
						
							|  |  |  |         "Found %d libraries:\n" % result["total"], | 
					
						
							|  |  |  |         fg="green" if result["total"] else "yellow", | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2014-09-24 22:18:19 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     while True: | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         for item in result["items"]: | 
					
						
							| 
									
										
										
										
											2016-12-29 01:31:44 +02:00
										 |  |  |             print_lib_item(item) | 
					
						
							| 
									
										
										
										
											2014-09-24 22:18:19 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         if int(result["page"]) * int(result["perpage"]) >= int(result["total"]): | 
					
						
							| 
									
										
										
										
											2014-09-24 22:18:19 +03:00
										 |  |  |             break | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-26 11:46:59 +03:00
										 |  |  |         if noninteractive: | 
					
						
							|  |  |  |             click.echo() | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |             click.secho( | 
					
						
							|  |  |  |                 "Loading next %d libraries... Press Ctrl+C to stop!" | 
					
						
							|  |  |  |                 % result["perpage"], | 
					
						
							|  |  |  |                 fg="yellow", | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2016-08-26 11:46:59 +03:00
										 |  |  |             click.echo() | 
					
						
							| 
									
										
										
										
											2018-01-16 00:57:06 +02:00
										 |  |  |             time.sleep(5) | 
					
						
							| 
									
										
										
										
											2016-08-26 11:46:59 +03:00
										 |  |  |         elif not click.confirm("Show next libraries?"): | 
					
						
							| 
									
										
										
										
											2014-09-24 22:18:19 +03:00
										 |  |  |             break | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         result = util.get_api_result( | 
					
						
							|  |  |  |             "/v2/lib/search", | 
					
						
							|  |  |  |             {"query": " ".join(query), "page": int(result["page"]) + 1}, | 
					
						
							|  |  |  |             cache_valid="1d", | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2014-09-04 18:58:12 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-28 15:48:36 +02:00
										 |  |  | @cli.command("builtin", short_help="List built-in libraries") | 
					
						
							|  |  |  | @click.option("--storage", multiple=True) | 
					
						
							|  |  |  | @click.option("--json-output", is_flag=True) | 
					
						
							|  |  |  | def lib_builtin(storage, json_output): | 
					
						
							|  |  |  |     items = get_builtin_libs(storage) | 
					
						
							| 
									
										
										
										
											2017-01-15 00:12:41 +02:00
										 |  |  |     if json_output: | 
					
						
							| 
									
										
										
										
											2019-06-05 17:57:22 +03:00
										 |  |  |         return click.echo(dump_json_to_unicode(items)) | 
					
						
							| 
									
										
										
										
											2017-01-15 00:12:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-15 16:36:59 +03:00
										 |  |  |     for storage_ in items: | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         if not storage_["items"]: | 
					
						
							| 
									
										
										
										
											2017-01-15 00:12:41 +02:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         click.secho(storage_["name"], fg="green") | 
					
						
							|  |  |  |         click.echo("*" * len(storage_["name"])) | 
					
						
							| 
									
										
										
										
											2017-01-15 00:12:41 +02:00
										 |  |  |         click.echo() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         for item in sorted(storage_["items"], key=lambda i: i["name"]): | 
					
						
							| 
									
										
										
										
											2017-01-15 00:12:41 +02:00
										 |  |  |             print_lib_item(item) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-15 22:16:37 +02:00
										 |  |  |     return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-15 00:12:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 15:55:08 +02:00
										 |  |  | @cli.command("show", short_help="Show detailed info about a library") | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  | @click.argument("library", metavar="[LIBRARY]") | 
					
						
							| 
									
										
										
										
											2016-12-28 15:55:08 +02:00
										 |  |  | @click.option("--json-output", is_flag=True) | 
					
						
							|  |  |  | def lib_show(library, json_output): | 
					
						
							|  |  |  |     lm = LibraryManager() | 
					
						
							| 
									
										
										
										
											2017-11-25 00:31:16 +02:00
										 |  |  |     name, requirements, _ = lm.parse_pkg_uri(library) | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |     lib_id = lm.search_lib_id( | 
					
						
							|  |  |  |         {"name": name, "requirements": requirements}, | 
					
						
							|  |  |  |         silent=json_output, | 
					
						
							|  |  |  |         interactive=not json_output, | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2019-05-07 22:13:21 +03:00
										 |  |  |     lib = util.get_api_result("/lib/info/%d" % lib_id, cache_valid="1d") | 
					
						
							| 
									
										
										
										
											2016-12-28 15:55:08 +02:00
										 |  |  |     if json_output: | 
					
						
							| 
									
										
										
										
											2019-06-05 17:57:22 +03:00
										 |  |  |         return click.echo(dump_json_to_unicode(lib)) | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |     click.secho(lib["name"], fg="cyan") | 
					
						
							|  |  |  |     click.echo("=" * len(lib["name"])) | 
					
						
							|  |  |  |     click.secho("#ID: %d" % lib["id"], bold=True) | 
					
						
							|  |  |  |     click.echo(lib["description"]) | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  |     click.echo() | 
					
						
							| 
									
										
										
										
											2014-09-04 18:58:12 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-16 00:57:06 +02:00
										 |  |  |     click.echo( | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         "Version: %s, released %s" | 
					
						
							|  |  |  |         % ( | 
					
						
							|  |  |  |             lib["version"]["name"], | 
					
						
							|  |  |  |             time.strftime("%c", util.parse_date(lib["version"]["released"])), | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     click.echo("Manifest: %s" % lib["confurl"]) | 
					
						
							| 
									
										
										
										
											2016-12-28 15:55:08 +02:00
										 |  |  |     for key in ("homepage", "repository", "license"): | 
					
						
							|  |  |  |         if key not in lib or not lib[key]: | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         if isinstance(lib[key], list): | 
					
						
							|  |  |  |             click.echo("%s: %s" % (key.title(), ", ".join(lib[key]))) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             click.echo("%s: %s" % (key.title(), lib[key])) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     blocks = [] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-19 00:14:11 +03:00
										 |  |  |     _authors = [] | 
					
						
							| 
									
										
										
										
											2016-12-28 15:55:08 +02:00
										 |  |  |     for author in lib.get("authors", []): | 
					
						
							| 
									
										
										
										
											2014-09-04 18:58:12 +03:00
										 |  |  |         _data = [] | 
					
						
							| 
									
										
										
										
											2014-10-19 00:14:11 +03:00
										 |  |  |         for key in ("name", "email", "url", "maintainer"): | 
					
						
							|  |  |  |             if not author[key]: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             if key == "email": | 
					
						
							|  |  |  |                 _data.append("<%s>" % author[key]) | 
					
						
							|  |  |  |             elif key == "maintainer": | 
					
						
							| 
									
										
										
										
											2014-10-19 00:21:10 +03:00
										 |  |  |                 _data.append("(maintainer)") | 
					
						
							| 
									
										
										
										
											2014-10-19 00:14:11 +03:00
										 |  |  |             else: | 
					
						
							|  |  |  |                 _data.append(author[key]) | 
					
						
							|  |  |  |         _authors.append(" ".join(_data)) | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  |     if _authors: | 
					
						
							| 
									
										
										
										
											2016-12-28 15:55:08 +02:00
										 |  |  |         blocks.append(("Authors", _authors)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |     blocks.append(("Keywords", lib["keywords"])) | 
					
						
							| 
									
										
										
										
											2016-12-29 01:31:44 +02:00
										 |  |  |     for key in ("frameworks", "platforms"): | 
					
						
							|  |  |  |         if key not in lib or not lib[key]: | 
					
						
							|  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         blocks.append(("Compatible %s" % key, [i["title"] for i in lib[key]])) | 
					
						
							|  |  |  |     blocks.append(("Headers", lib["headers"])) | 
					
						
							|  |  |  |     blocks.append(("Examples", lib["examples"])) | 
					
						
							|  |  |  |     blocks.append( | 
					
						
							|  |  |  |         ( | 
					
						
							|  |  |  |             "Versions", | 
					
						
							|  |  |  |             [ | 
					
						
							|  |  |  |                 "%s, released %s" | 
					
						
							|  |  |  |                 % (v["name"], time.strftime("%c", util.parse_date(v["released"]))) | 
					
						
							|  |  |  |                 for v in lib["versions"] | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     blocks.append( | 
					
						
							|  |  |  |         ( | 
					
						
							|  |  |  |             "Unique Downloads", | 
					
						
							|  |  |  |             [ | 
					
						
							|  |  |  |                 "Today: %s" % lib["dlstats"]["day"], | 
					
						
							|  |  |  |                 "Week: %s" % lib["dlstats"]["week"], | 
					
						
							|  |  |  |                 "Month: %s" % lib["dlstats"]["month"], | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2016-12-28 15:55:08 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (title, rows) in blocks: | 
					
						
							|  |  |  |         click.echo() | 
					
						
							|  |  |  |         click.secho(title, bold=True) | 
					
						
							|  |  |  |         click.echo("-" * len(title)) | 
					
						
							|  |  |  |         for row in rows: | 
					
						
							|  |  |  |             click.echo(row) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-15 22:16:37 +02:00
										 |  |  |     return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 15:55:08 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | @cli.command("register", short_help="Register a new library") | 
					
						
							| 
									
										
										
										
											2014-09-24 22:18:19 +03:00
										 |  |  | @click.argument("config_url") | 
					
						
							| 
									
										
										
										
											2014-09-08 22:02:57 +03:00
										 |  |  | def lib_register(config_url): | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |     if not config_url.startswith("http://") and not config_url.startswith("https://"): | 
					
						
							| 
									
										
										
										
											2014-12-16 23:45:00 +02:00
										 |  |  |         raise exception.InvalidLibConfURL(config_url) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-30 23:45:03 +03:00
										 |  |  |     # Validate manifest | 
					
						
							| 
									
										
										
										
											2019-12-29 13:13:04 +02:00
										 |  |  |     ManifestSchema().load_manifest( | 
					
						
							| 
									
										
										
										
											2019-10-17 00:17:16 +03:00
										 |  |  |         ManifestParserFactory.new_from_url(config_url).as_dict() | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2019-09-30 17:59:06 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |     result = util.get_api_result("/lib/register", data=dict(config_url=config_url)) | 
					
						
							|  |  |  |     if "message" in result and result["message"]: | 
					
						
							|  |  |  |         click.secho( | 
					
						
							|  |  |  |             result["message"], | 
					
						
							|  |  |  |             fg="green" if "successed" in result and result["successed"] else "red", | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2016-12-23 21:57:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @cli.command("stats", short_help="Library Registry Statistics") | 
					
						
							|  |  |  | @click.option("--json-output", is_flag=True) | 
					
						
							|  |  |  | def lib_stats(json_output): | 
					
						
							| 
									
										
										
										
											2019-05-07 22:13:21 +03:00
										 |  |  |     result = util.get_api_result("/lib/stats", cache_valid="1h") | 
					
						
							| 
									
										
										
										
											2016-12-23 21:57:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if json_output: | 
					
						
							| 
									
										
										
										
											2019-06-05 17:57:22 +03:00
										 |  |  |         return click.echo(dump_json_to_unicode(result)) | 
					
						
							| 
									
										
										
										
											2016-12-23 21:57:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for key in ("updated", "added"): | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         tabular_data = [ | 
					
						
							|  |  |  |             ( | 
					
						
							|  |  |  |                 click.style(item["name"], fg="cyan"), | 
					
						
							|  |  |  |                 time.strftime("%c", util.parse_date(item["date"])), | 
					
						
							|  |  |  |                 "https://platformio.org/lib/show/%s/%s" | 
					
						
							|  |  |  |                 % (item["id"], quote(item["name"])), | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             for item in result.get(key, []) | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |         table = tabulate( | 
					
						
							|  |  |  |             tabular_data, | 
					
						
							|  |  |  |             headers=[click.style("RECENTLY " + key.upper(), bold=True), "Date", "URL"], | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-08-17 20:55:16 +03:00
										 |  |  |         click.echo(table) | 
					
						
							| 
									
										
										
										
											2016-12-23 21:57:11 +02:00
										 |  |  |         click.echo() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-17 20:55:16 +03:00
										 |  |  |     for key in ("lastkeywords", "topkeywords"): | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         tabular_data = [ | 
					
						
							|  |  |  |             ( | 
					
						
							|  |  |  |                 click.style(name, fg="cyan"), | 
					
						
							|  |  |  |                 "https://platformio.org/lib/search?query=" + quote("keyword:%s" % name), | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             for name in result.get(key, []) | 
					
						
							|  |  |  |         ] | 
					
						
							| 
									
										
										
										
											2019-08-17 20:55:16 +03:00
										 |  |  |         table = tabulate( | 
					
						
							|  |  |  |             tabular_data, | 
					
						
							|  |  |  |             headers=[ | 
					
						
							|  |  |  |                 click.style( | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |                     ("RECENT" if key == "lastkeywords" else "POPULAR") + " KEYWORDS", | 
					
						
							|  |  |  |                     bold=True, | 
					
						
							|  |  |  |                 ), | 
					
						
							|  |  |  |                 "URL", | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-08-17 20:55:16 +03:00
										 |  |  |         click.echo(table) | 
					
						
							|  |  |  |         click.echo() | 
					
						
							| 
									
										
										
										
											2016-12-23 21:57:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |     for key, title in (("dlday", "Today"), ("dlweek", "Week"), ("dlmonth", "Month")): | 
					
						
							|  |  |  |         tabular_data = [ | 
					
						
							|  |  |  |             ( | 
					
						
							|  |  |  |                 click.style(item["name"], fg="cyan"), | 
					
						
							|  |  |  |                 "https://platformio.org/lib/show/%s/%s" | 
					
						
							|  |  |  |                 % (item["id"], quote(item["name"])), | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             for item in result.get(key, []) | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |         table = tabulate( | 
					
						
							|  |  |  |             tabular_data, | 
					
						
							|  |  |  |             headers=[click.style("FEATURED: " + title.upper(), bold=True), "URL"], | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-08-17 20:55:16 +03:00
										 |  |  |         click.echo(table) | 
					
						
							| 
									
										
										
										
											2016-12-23 21:57:11 +02:00
										 |  |  |         click.echo() | 
					
						
							| 
									
										
										
										
											2017-12-15 22:16:37 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return True | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def print_storage_header(storage_dirs, storage_dir): | 
					
						
							|  |  |  |     if storage_dirs and storage_dirs[0] != storage_dir: | 
					
						
							|  |  |  |         click.echo("") | 
					
						
							|  |  |  |     click.echo( | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         click.style("Library Storage: ", bold=True) | 
					
						
							|  |  |  |         + click.style(storage_dir, fg="blue") | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def print_lib_item(item): | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |     click.secho(item["name"], fg="cyan") | 
					
						
							|  |  |  |     click.echo("=" * len(item["name"])) | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  |     if "id" in item: | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         click.secho("#ID: %d" % item["id"], bold=True) | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  |     if "description" in item or "url" in item: | 
					
						
							|  |  |  |         click.echo(item.get("description", item.get("url", ""))) | 
					
						
							|  |  |  |     click.echo() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for key in ("version", "homepage", "license", "keywords"): | 
					
						
							|  |  |  |         if key not in item or not item[key]: | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         if isinstance(item[key], list): | 
					
						
							|  |  |  |             click.echo("%s: %s" % (key.title(), ", ".join(item[key]))) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             click.echo("%s: %s" % (key.title(), item[key])) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for key in ("frameworks", "platforms"): | 
					
						
							|  |  |  |         if key not in item: | 
					
						
							|  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         click.echo( | 
					
						
							|  |  |  |             "Compatible %s: %s" | 
					
						
							|  |  |  |             % ( | 
					
						
							|  |  |  |                 key, | 
					
						
							|  |  |  |                 ", ".join( | 
					
						
							|  |  |  |                     [i["title"] if isinstance(i, dict) else i for i in item[key]] | 
					
						
							|  |  |  |                 ), | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if "authors" in item or "authornames" in item: | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         click.echo( | 
					
						
							|  |  |  |             "Authors: %s" | 
					
						
							|  |  |  |             % ", ".join( | 
					
						
							|  |  |  |                 item.get( | 
					
						
							|  |  |  |                     "authornames", [a.get("name", "") for a in item.get("authors", [])] | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if "__src_url" in item: | 
					
						
							| 
									
										
										
										
											2019-09-23 23:13:48 +03:00
										 |  |  |         click.secho("Source: %s" % item["__src_url"]) | 
					
						
							| 
									
										
										
										
											2019-05-23 00:23:24 +03:00
										 |  |  |     click.echo() |