diff --git a/.gitignore b/.gitignore index ab3dadd9..b46dd1cb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +venv* __pycache__/ *.py[co] *.egg diff --git a/README.md b/README.md index 70b63b83..969a8a68 100644 --- a/README.md +++ b/README.md @@ -143,7 +143,7 @@ python3 -m twine upload dist/mergin-client-x.y.z.tar.gz ### Installing deps -Python 3.7+ required. Create `mergin/deps` folder where [geodiff](https://github.com/lutraconsulting/geodiff) lib is supposed to be and install dependencies: +Python 3.7+ required. Create `mergin/deps` folder where [geodiff](https://github.com/MerginMaps/geodiff) lib is supposed to be and install dependencies: ``` rm -r mergin/deps mkdir mergin/deps diff --git a/mergin/cli.py b/mergin/cli.py index 77033584..b5691c8f 100755 --- a/mergin/cli.py +++ b/mergin/cli.py @@ -223,16 +223,41 @@ def create(ctx, project, public, from_dir): help="What kind of projects (e.g. 'created' for just my projects," "'shared' for projects shared with me. No flag means returns all public projects.", ) +@click.option( + "--name", + help="Filter projects with name like name", +) +@click.option( + "--namespace", + help="Filter projects with namespace like namespace", +) +@click.option( + "--order_params", + help="optional attributes for sorting the list. " + "It should be a comma separated attribute names " + "with _asc or _desc appended for sorting direction. " + "For example: \"namespace_asc,disk_usage_desc\". " + "Available attrs: namespace, name, created, updated, disk_usage, creator", +) @click.pass_context -def list_projects(ctx, flag): +def list_projects(ctx, flag, name, namespace, order_params): """List projects on the server.""" filter_str = "(filter flag={})".format(flag) if flag is not None else "(all public)" + click.echo("List of projects {}:".format(filter_str)) + mc = ctx.obj["client"] if mc is None: return - resp = mc.paginated_projects_list(flag=flag) - projects_list = resp["projects"] + + projects_list = mc.projects_list( + flag=flag, + name=name, + namespace=namespace, + order_params=order_params + ) + + click.echo("Fetched {} projects .".format(len(projects_list))) for project in projects_list: full_name = "{} / {}".format(project["namespace"], project["name"]) click.echo( diff --git a/mergin/client.py b/mergin/client.py index 5a4ded8d..8a808345 100644 --- a/mergin/client.py +++ b/mergin/client.py @@ -424,10 +424,11 @@ def paginated_projects_list(self, page=1, per_page=50, tags=None, user=None, fla projects = json.load(resp) return projects - def projects_list(self, tags=None, user=None, flag=None, q=None): + def projects_list(self, tags=None, user=None, flag=None, name=None, namespace=None, order_params=None): """ - Find all available Mergin Maps projects. It will always retrieve max 100 projects. - Consider using the paginated_projects_list instead. + Find all available Mergin Maps projects. + + Calls paginated_projects_list for all pages. Can take significant time to fetch all pages. :param tags: Filter projects by tags ('valid_qgis', 'mappin_use', input_use') :type tags: List @@ -438,22 +439,40 @@ def projects_list(self, tags=None, user=None, flag=None, q=None): :param flag: Predefined filter flag ('created', 'shared') :type flag: String - :param q: Search query string - :type q: String + :param name: Filter projects with name like name + :type name: String + + :param namespace: Filter projects with namespace like namespace + :type namespace: String + + :param order_params: optional attributes for sorting the list. It should be a comma separated attribute names + with _asc or _desc appended for sorting direction. For example: "namespace_asc,disk_usage_desc". + Available attrs: namespace, name, created, updated, disk_usage, creator + :type order_params: String :rtype: List[Dict] """ - params = {} - if tags: - params["tags"] = ",".join(tags) - if user: - params["user"] = user - if flag: - params["flag"] = flag - if q: - params["q"] = q - resp = self.get("/v1/project", params) - projects = json.load(resp) + projects = [] + page_i = 1 + fetched_projects = 0 + while True: + resp = self.paginated_projects_list( + page=page_i, + per_page=50, + tags=tags, + user=user, + flag=flag, + name=name, + namespace=namespace, + order_params=order_params + ) + fetched_projects += len(resp["projects"]) + count = resp["count"] + projects += resp["projects"] + if fetched_projects < count: + page_i += 1 + else: + break return projects def project_info(self, project_path, since=None, version=None): diff --git a/setup.py b/setup.py index 2d5995ea..60c9e451 100644 --- a/setup.py +++ b/setup.py @@ -17,10 +17,10 @@ platforms='any', install_requires=[ - 'python-dateutil==2.6.0', - 'pygeodiff==1.0.5', - 'pytz==2019.3', - 'click', + 'python-dateutil==2.8.2', + 'pygeodiff==1.0.6', + 'pytz==2022.1', + 'click==8.1.3', ], entry_points={