| 
									
										
										
										
											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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-05 22:58:55 +02:00
										 |  |  | import json | 
					
						
							| 
									
										
										
										
											2018-01-16 00:57:06 +02:00
										 |  |  | import time | 
					
						
							| 
									
										
										
										
											2017-03-08 17:24:58 +02:00
										 |  |  | from os.path import isdir, join | 
					
						
							| 
									
										
										
										
											2016-12-23 21:57:11 +02:00
										 |  |  | from urllib import quote | 
					
						
							| 
									
										
										
										
											2015-01-05 22:58:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-24 22:18:19 +03:00
										 |  |  | import click | 
					
						
							| 
									
										
										
										
											2014-09-04 18:58:12 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-26 11:46:59 +03:00
										 |  |  | from platformio import exception, util | 
					
						
							| 
									
										
										
										
											2018-01-13 19:44:05 +02:00
										 |  |  | from platformio.managers.lib import LibraryManager, get_builtin_libs | 
					
						
							| 
									
										
										
										
											2015-05-01 12:54:45 +01:00
										 |  |  | from platformio.util import get_api_result | 
					
						
							| 
									
										
										
										
											2014-09-03 23:03:49 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | @click.group(short_help="Library Manager") | 
					
						
							|  |  |  | @click.option( | 
					
						
							|  |  |  |     "-g", | 
					
						
							|  |  |  |     "--global", | 
					
						
							|  |  |  |     is_flag=True, | 
					
						
							| 
									
										
										
										
											2017-12-19 15:49:44 +02:00
										 |  |  |     help="Manage global PlatformIO library storage") | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  | @click.option( | 
					
						
							|  |  |  |     "-d", | 
					
						
							|  |  |  |     "--storage-dir", | 
					
						
							|  |  |  |     default=None, | 
					
						
							|  |  |  |     type=click.Path( | 
					
						
							|  |  |  |         exists=True, | 
					
						
							|  |  |  |         file_okay=False, | 
					
						
							|  |  |  |         dir_okay=True, | 
					
						
							|  |  |  |         writable=True, | 
					
						
							|  |  |  |         resolve_path=True), | 
					
						
							|  |  |  |     help="Manage custom library storage") | 
					
						
							|  |  |  | @click.pass_context | 
					
						
							|  |  |  | def cli(ctx, **options): | 
					
						
							| 
									
										
										
										
											2017-01-15 00:12:41 +02:00
										 |  |  |     non_storage_cmds = ("search", "show", "register", "stats", "builtin") | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  |     # skip commands that don't need storage folder | 
					
						
							| 
									
										
										
										
											2017-01-15 00:12:41 +02:00
										 |  |  |     if ctx.invoked_subcommand in non_storage_cmds or \ | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  |             (len(ctx.args) == 2 and ctx.args[1] in ("-h", "--help")): | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     storage_dir = options['storage_dir'] | 
					
						
							| 
									
										
										
										
											2016-08-10 19:39:17 +03:00
										 |  |  |     if not storage_dir: | 
					
						
							|  |  |  |         if options['global']: | 
					
						
							|  |  |  |             storage_dir = join(util.get_home_dir(), "lib") | 
					
						
							|  |  |  |         elif util.is_platformio_project(): | 
					
						
							|  |  |  |             storage_dir = util.get_projectlibdeps_dir() | 
					
						
							| 
									
										
										
										
											2016-09-01 01:30:14 +03:00
										 |  |  |         elif util.is_ci(): | 
					
						
							|  |  |  |             storage_dir = join(util.get_home_dir(), "lib") | 
					
						
							|  |  |  |             click.secho( | 
					
						
							|  |  |  |                 "Warning! Global library storage is used automatically. " | 
					
						
							|  |  |  |                 "Please use `platformio lib --global %s` command to remove " | 
					
						
							|  |  |  |                 "this warning." % ctx.invoked_subcommand, | 
					
						
							|  |  |  |                 fg="yellow") | 
					
						
							| 
									
										
										
										
											2017-07-13 00:51:04 +03:00
										 |  |  |     elif util.is_platformio_project(storage_dir): | 
					
						
							|  |  |  |         with util.cd(storage_dir): | 
					
						
							|  |  |  |             storage_dir = util.get_projectlibdeps_dir() | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if not storage_dir and not util.is_platformio_project(): | 
					
						
							| 
									
										
										
										
											2016-08-26 12:30:37 +03:00
										 |  |  |         raise exception.NotGlobalLibDir(util.get_project_dir(), | 
					
						
							|  |  |  |                                         join(util.get_home_dir(), "lib"), | 
					
						
							|  |  |  |                                         ctx.invoked_subcommand) | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     ctx.obj = LibraryManager(storage_dir) | 
					
						
							| 
									
										
										
										
											2016-08-10 19:39:17 +03:00
										 |  |  |     if "--json-output" not in ctx.args: | 
					
						
							|  |  |  |         click.echo("Library Storage: " + storage_dir) | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @cli.command("install", short_help="Install library") | 
					
						
							|  |  |  | @click.argument("libraries", required=False, nargs=-1, metavar="[LIBRARY...]") | 
					
						
							| 
									
										
										
										
											2016-08-21 00:31:58 +03:00
										 |  |  | # @click.option( | 
					
						
							|  |  |  | #     "--save", | 
					
						
							|  |  |  | #     is_flag=True, | 
					
						
							|  |  |  | #     help="Save installed libraries into the project's platformio.ini " | 
					
						
							|  |  |  | #     "library dependencies") | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  | @click.option( | 
					
						
							| 
									
										
										
										
											2016-08-21 00:31:58 +03:00
										 |  |  |     "-s", "--silent", is_flag=True, help="Suppress progress reporting") | 
					
						
							| 
									
										
										
										
											2016-08-26 11:46:59 +03:00
										 |  |  | @click.option( | 
					
						
							|  |  |  |     "--interactive", | 
					
						
							|  |  |  |     is_flag=True, | 
					
						
							|  |  |  |     help="Allow to make a choice for all prompts") | 
					
						
							| 
									
										
										
										
											2017-12-19 00:51:35 +02:00
										 |  |  | @click.option( | 
					
						
							|  |  |  |     "-f", | 
					
						
							|  |  |  |     "--force", | 
					
						
							|  |  |  |     is_flag=True, | 
					
						
							|  |  |  |     help="Reinstall/redownload library if exists") | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  | @click.pass_obj | 
					
						
							| 
									
										
										
										
											2017-12-19 00:51:35 +02:00
										 |  |  | def lib_install(lm, libraries, silent, interactive, force): | 
					
						
							| 
									
										
										
										
											2018-01-13 19:44:05 +02:00
										 |  |  |     # @TODO: "save" option | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  |     for library in libraries: | 
					
						
							| 
									
										
										
										
											2017-12-19 00:51:35 +02:00
										 |  |  |         lm.install( | 
					
						
							|  |  |  |             library, silent=silent, interactive=interactive, force=force) | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @cli.command("uninstall", short_help="Uninstall libraries") | 
					
						
							|  |  |  | @click.argument("libraries", nargs=-1, metavar="[LIBRARY...]") | 
					
						
							|  |  |  | @click.pass_obj | 
					
						
							|  |  |  | def lib_uninstall(lm, libraries): | 
					
						
							|  |  |  |     for library in libraries: | 
					
						
							|  |  |  |         lm.uninstall(library) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @cli.command("update", short_help="Update installed libraries") | 
					
						
							|  |  |  | @click.argument("libraries", required=False, nargs=-1, metavar="[LIBRARY...]") | 
					
						
							|  |  |  | @click.option( | 
					
						
							|  |  |  |     "-c", | 
					
						
							|  |  |  |     "--only-check", | 
					
						
							|  |  |  |     is_flag=True, | 
					
						
							|  |  |  |     help="Do not update, only check for new version") | 
					
						
							| 
									
										
										
										
											2017-01-30 01:04:06 +02:00
										 |  |  | @click.option("--json-output", is_flag=True) | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  | @click.pass_obj | 
					
						
							| 
									
										
										
										
											2017-01-30 01:04:06 +02:00
										 |  |  | def lib_update(lm, libraries, only_check, json_output): | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  |     if not libraries: | 
					
						
							| 
									
										
										
										
											2017-03-08 17:24:58 +02:00
										 |  |  |         libraries = [manifest['__pkg_dir'] for manifest in lm.get_installed()] | 
					
						
							| 
									
										
										
										
											2017-01-30 01:04:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if only_check and json_output: | 
					
						
							|  |  |  |         result = [] | 
					
						
							|  |  |  |         for library in libraries: | 
					
						
							| 
									
										
										
										
											2017-03-08 17:24:58 +02:00
										 |  |  |             pkg_dir = library if isdir(library) else None | 
					
						
							|  |  |  |             requirements = None | 
					
						
							|  |  |  |             url = None | 
					
						
							|  |  |  |             if not pkg_dir: | 
					
						
							| 
									
										
										
										
											2017-11-25 00:31:16 +02:00
										 |  |  |                 name, requirements, url = lm.parse_pkg_uri(library) | 
					
						
							| 
									
										
										
										
											2017-03-08 17:24:58 +02:00
										 |  |  |                 pkg_dir = lm.get_package_dir(name, requirements, url) | 
					
						
							|  |  |  |             if not pkg_dir: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             latest = lm.outdated(pkg_dir, requirements) | 
					
						
							| 
									
										
										
										
											2017-03-04 18:37:03 +02:00
										 |  |  |             if not latest: | 
					
						
							| 
									
										
										
										
											2017-01-30 01:04:06 +02:00
										 |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2017-03-08 17:24:58 +02:00
										 |  |  |             manifest = lm.load_manifest(pkg_dir) | 
					
						
							| 
									
										
										
										
											2017-02-01 19:07:53 +02:00
										 |  |  |             manifest['versionLatest'] = latest | 
					
						
							| 
									
										
										
										
											2017-01-30 01:04:06 +02:00
										 |  |  |             result.append(manifest) | 
					
						
							|  |  |  |         return click.echo(json.dumps(result)) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         for library in libraries: | 
					
						
							|  |  |  |             lm.update(library, only_check=only_check) | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-29 01:31:44 +02:00
										 |  |  | def print_lib_item(item): | 
					
						
							|  |  |  |     click.secho(item['name'], fg="cyan") | 
					
						
							|  |  |  |     click.echo("=" * len(item['name'])) | 
					
						
							|  |  |  |     if "id" in item: | 
					
						
							|  |  |  |         click.secho("#ID: %d" % item['id'], bold=True) | 
					
						
							| 
									
										
										
										
											2017-01-28 17:06:20 +02:00
										 |  |  |     if "description" in item or "url" in item: | 
					
						
							|  |  |  |         click.echo(item.get("description", item.get("url", ""))) | 
					
						
							| 
									
										
										
										
											2016-12-29 01:31:44 +02:00
										 |  |  |     click.echo() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-15 00:12:41 +02:00
										 |  |  |     for key in ("version", "homepage", "license", "keywords"): | 
					
						
							| 
									
										
										
										
											2016-12-29 01:31:44 +02:00
										 |  |  |         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 | 
					
						
							|  |  |  |         click.echo("Compatible %s: %s" % (key, ", ".join( | 
					
						
							|  |  |  |             [i['title'] if isinstance(i, dict) else i for i in item[key]]))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if "authors" in item or "authornames" in item: | 
					
						
							|  |  |  |         click.echo("Authors: %s" % ", ".join( | 
					
						
							|  |  |  |             item.get("authornames", | 
					
						
							|  |  |  |                      [a.get("name", "") for a in item.get("authors", [])]))) | 
					
						
							| 
									
										
										
										
											2017-03-08 17:24:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if "__src_url" in item: | 
					
						
							|  |  |  |         click.secho("Source: %s" % item['__src_url']) | 
					
						
							| 
									
										
										
										
											2016-12-29 01:31:44 +02:00
										 |  |  |     click.echo() | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							| 
									
										
										
										
											2016-08-26 11:46:59 +03:00
										 |  |  | @click.option( | 
					
						
							|  |  |  |     "--noninteractive", | 
					
						
							|  |  |  |     is_flag=True, | 
					
						
							|  |  |  |     help="Do not prompt, automatically paginate with delay") | 
					
						
							|  |  |  | 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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-19 00:14:11 +03:00
										 |  |  |     for key, values in filters.iteritems(): | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  |     result = get_api_result( | 
					
						
							| 
									
										
										
										
											2016-12-29 01:31:44 +02:00
										 |  |  |         "/v2/lib/search", | 
					
						
							| 
									
										
										
										
											2017-03-02 17:09:22 +02:00
										 |  |  |         dict(query=" ".join(query), page=page), | 
					
						
							| 
									
										
										
										
											2017-09-09 20:57:25 +03:00
										 |  |  |         cache_valid="1d") | 
					
						
							| 
									
										
										
										
											2016-04-24 00:01:42 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if json_output: | 
					
						
							|  |  |  |         click.echo(json.dumps(result)) | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-16 23:45:00 +02:00
										 |  |  |     if result['total'] == 0: | 
					
						
							|  |  |  |         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", | 
					
						
							|  |  |  |             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") | 
					
						
							|  |  |  |         click.echo("For more examples and advanced search syntax, " | 
					
						
							|  |  |  |                    "please use documentation:") | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  |         click.secho( | 
					
						
							| 
									
										
										
										
											2016-12-05 21:25:10 +02:00
										 |  |  |             "http://docs.platformio.org/page/userguide/lib/cmd_search.html\n", | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  |             fg="cyan") | 
					
						
							| 
									
										
										
										
											2014-12-16 23:45:00 +02:00
										 |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +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: | 
					
						
							|  |  |  |         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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-01 14:10:32 +02: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() | 
					
						
							|  |  |  |             click.secho( | 
					
						
							|  |  |  |                 "Loading next %d libraries... Press Ctrl+C to stop!" % | 
					
						
							|  |  |  |                 result['perpage'], | 
					
						
							|  |  |  |                 fg="yellow") | 
					
						
							|  |  |  |             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 | 
					
						
							| 
									
										
										
										
											2016-08-26 11:46:59 +03:00
										 |  |  |         result = get_api_result( | 
					
						
							| 
									
										
										
										
											2016-12-29 01:31:44 +02:00
										 |  |  |             "/v2/lib/search", | 
					
						
							| 
									
										
										
										
											2017-01-28 17:06:20 +02:00
										 |  |  |             {"query": " ".join(query), | 
					
						
							|  |  |  |              "page": int(result['page']) + 1}, | 
					
						
							| 
									
										
										
										
											2017-09-09 20:57:25 +03:00
										 |  |  |             cache_valid="1d") | 
					
						
							| 
									
										
										
										
											2014-09-04 18:58:12 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @cli.command("list", short_help="List installed libraries") | 
					
						
							| 
									
										
										
										
											2015-01-02 21:03:14 +02:00
										 |  |  | @click.option("--json-output", is_flag=True) | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  | @click.pass_obj | 
					
						
							|  |  |  | def lib_list(lm, json_output): | 
					
						
							|  |  |  |     items = lm.get_installed() | 
					
						
							| 
									
										
										
										
											2015-01-02 21:03:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if json_output: | 
					
						
							| 
									
										
										
										
											2016-12-28 15:55:08 +02:00
										 |  |  |         return click.echo(json.dumps(items)) | 
					
						
							| 
									
										
										
										
											2015-01-02 21:03:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-19 00:14:11 +03:00
										 |  |  |     if not items: | 
					
						
							| 
									
										
										
										
											2017-12-15 22:16:37 +02:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2014-10-19 00:14:11 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  |     for item in sorted(items, key=lambda i: i['name']): | 
					
						
							| 
									
										
										
										
											2016-12-29 01:31:44 +02:00
										 |  |  |         print_lib_item(item) | 
					
						
							| 
									
										
										
										
											2014-09-04 18:58:12 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-15 22:16:37 +02:00
										 |  |  |     return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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: | 
					
						
							|  |  |  |         return click.echo(json.dumps(items)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-15 16:36:59 +03:00
										 |  |  |     for storage_ in items: | 
					
						
							|  |  |  |         if not storage_['items']: | 
					
						
							| 
									
										
										
										
											2017-01-15 00:12:41 +02:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2017-04-15 16:36:59 +03:00
										 |  |  |         click.secho(storage_['name'], fg="green") | 
					
						
							|  |  |  |         click.echo("*" * len(storage_['name'])) | 
					
						
							| 
									
										
										
										
											2017-01-15 00:12:41 +02:00
										 |  |  |         click.echo() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-15 16:36:59 +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) | 
					
						
							| 
									
										
										
										
											2018-01-13 19:44:05 +02:00
										 |  |  |     lib_id = lm.search_lib_id( | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             "name": name, | 
					
						
							|  |  |  |             "requirements": requirements | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         silent=json_output, | 
					
						
							|  |  |  |         interactive=not json_output) | 
					
						
							| 
									
										
										
										
											2016-12-28 15:55:08 +02:00
										 |  |  |     lib = get_api_result("/lib/info/%d" % lib_id, cache_valid="1d") | 
					
						
							|  |  |  |     if json_output: | 
					
						
							|  |  |  |         return click.echo(json.dumps(lib)) | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 15:55:08 +02:00
										 |  |  |     click.secho(lib['name'], fg="cyan") | 
					
						
							|  |  |  |     click.echo("=" * len(lib['name'])) | 
					
						
							| 
									
										
										
										
											2016-12-29 01:31:44 +02:00
										 |  |  |     click.secho("#ID: %d" % lib['id'], bold=True) | 
					
						
							| 
									
										
										
										
											2016-12-28 15:55:08 +02:00
										 |  |  |     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( | 
					
						
							|  |  |  |         "Version: %s, released %s" % | 
					
						
							|  |  |  |         (lib['version']['name'], | 
					
						
							|  |  |  |          time.strftime("%c", util.parse_date(lib['version']['released'])))) | 
					
						
							| 
									
										
										
										
											2016-12-28 15:55:08 +02:00
										 |  |  |     click.echo("Manifest: %s" % lib['confurl']) | 
					
						
							|  |  |  |     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)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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 | 
					
						
							|  |  |  |         blocks.append(("Compatible %s" % key, [i['title'] for i in lib[key]])) | 
					
						
							| 
									
										
										
										
											2016-12-28 15:55:08 +02:00
										 |  |  |     blocks.append(("Headers", lib['headers'])) | 
					
						
							|  |  |  |     blocks.append(("Examples", lib['examples'])) | 
					
						
							| 
									
										
										
										
											2018-01-16 00:57:06 +02:00
										 |  |  |     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", [ | 
					
						
							| 
									
										
										
										
											2017-06-05 16:05:05 +03:00
										 |  |  |         "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): | 
					
						
							| 
									
										
										
										
											2017-07-24 17:35:41 +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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-08 22:02:57 +03:00
										 |  |  |     result = get_api_result("/lib/register", data=dict(config_url=config_url)) | 
					
						
							|  |  |  |     if "message" in result and result['message']: | 
					
						
							| 
									
										
										
										
											2016-08-02 19:10:29 +03:00
										 |  |  |         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): | 
					
						
							|  |  |  |     result = get_api_result("/lib/stats", cache_valid="1h") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if json_output: | 
					
						
							|  |  |  |         return click.echo(json.dumps(result)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     printitem_tpl = "{name:<33} {url}" | 
					
						
							|  |  |  |     printitemdate_tpl = "{name:<33} {date:23} {url}" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _print_title(title): | 
					
						
							|  |  |  |         click.secho(title.upper(), bold=True) | 
					
						
							|  |  |  |         click.echo("*" * len(title)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _print_header(with_date=False): | 
					
						
							|  |  |  |         click.echo((printitemdate_tpl if with_date else printitem_tpl).format( | 
					
						
							| 
									
										
										
										
											2017-03-02 17:09:22 +02:00
										 |  |  |             name=click.style("Name", fg="cyan"), | 
					
						
							| 
									
										
										
										
											2016-12-23 21:57:11 +02:00
										 |  |  |             date="Date", | 
					
						
							| 
									
										
										
										
											2017-03-02 17:09:22 +02:00
										 |  |  |             url=click.style("Url", fg="blue"))) | 
					
						
							| 
									
										
										
										
											2016-12-23 21:57:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         terminal_width, _ = click.get_terminal_size() | 
					
						
							|  |  |  |         click.echo("-" * terminal_width) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _print_lib_item(item): | 
					
						
							| 
									
										
										
										
											2017-06-05 16:05:05 +03:00
										 |  |  |         click.echo((printitemdate_tpl | 
					
						
							|  |  |  |                     if "date" in item else printitem_tpl).format( | 
					
						
							|  |  |  |                         name=click.style(item['name'], fg="cyan"), | 
					
						
							| 
									
										
										
										
											2018-01-16 00:57:06 +02:00
										 |  |  |                         date=str( | 
					
						
							|  |  |  |                             time.strftime("%c", util.parse_date(item['date'])) | 
					
						
							|  |  |  |                             if "date" in item else ""), | 
					
						
							| 
									
										
										
										
											2017-06-05 16:05:05 +03:00
										 |  |  |                         url=click.style( | 
					
						
							| 
									
										
										
										
											2018-02-13 01:34:24 +02:00
										 |  |  |                             "https://platformio.org/lib/show/%s/%s" % | 
					
						
							| 
									
										
										
										
											2017-06-05 16:05:05 +03:00
										 |  |  |                             (item['id'], quote(item['name'])), | 
					
						
							|  |  |  |                             fg="blue"))) | 
					
						
							| 
									
										
										
										
											2016-12-23 21:57:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def _print_tag_item(name): | 
					
						
							|  |  |  |         click.echo( | 
					
						
							|  |  |  |             printitem_tpl.format( | 
					
						
							| 
									
										
										
										
											2017-03-02 17:09:22 +02:00
										 |  |  |                 name=click.style(name, fg="cyan"), | 
					
						
							| 
									
										
										
										
											2016-12-23 21:57:11 +02:00
										 |  |  |                 url=click.style( | 
					
						
							| 
									
										
										
										
											2018-02-13 01:34:24 +02:00
										 |  |  |                     "https://platformio.org/lib/search?query=" + | 
					
						
							| 
									
										
										
										
											2017-11-01 14:10:32 +02:00
										 |  |  |                     quote("keyword:%s" % name), | 
					
						
							| 
									
										
										
										
											2016-12-23 21:57:11 +02:00
										 |  |  |                     fg="blue"))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for key in ("updated", "added"): | 
					
						
							|  |  |  |         _print_title("Recently " + key) | 
					
						
							|  |  |  |         _print_header(with_date=True) | 
					
						
							|  |  |  |         for item in result.get(key, []): | 
					
						
							|  |  |  |             _print_lib_item(item) | 
					
						
							|  |  |  |         click.echo() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _print_title("Recent keywords") | 
					
						
							|  |  |  |     _print_header(with_date=False) | 
					
						
							|  |  |  |     for item in result.get("lastkeywords"): | 
					
						
							|  |  |  |         _print_tag_item(item) | 
					
						
							|  |  |  |     click.echo() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _print_title("Popular keywords") | 
					
						
							|  |  |  |     _print_header(with_date=False) | 
					
						
							|  |  |  |     for item in result.get("topkeywords"): | 
					
						
							|  |  |  |         _print_tag_item(item) | 
					
						
							|  |  |  |     click.echo() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-05 16:05:05 +03:00
										 |  |  |     for key, title in (("dlday", "Today"), ("dlweek", "Week"), ("dlmonth", | 
					
						
							|  |  |  |                                                                 "Month")): | 
					
						
							| 
									
										
										
										
											2016-12-23 21:57:11 +02:00
										 |  |  |         _print_title("Featured: " + title) | 
					
						
							|  |  |  |         _print_header(with_date=False) | 
					
						
							|  |  |  |         for item in result.get(key, []): | 
					
						
							|  |  |  |             _print_lib_item(item) | 
					
						
							|  |  |  |         click.echo() | 
					
						
							| 
									
										
										
										
											2017-12-15 22:16:37 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return True |