Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 54 additions & 4 deletions qfieldcloud_sdk/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,16 +349,46 @@ def list_files(ctx: Context, project_id):
"owner",
help="Owner of the project. If omitted, the current user is the owner.",
)
@click.option("--description", "description", help="Description of the project.")
@click.option(
"--description",
"description",
default="",
help="Description of the project.",
)
@click.option(
"--is-public/--is-private", "is_public", help="Mark the project as public."
)
@click.option(
"--project-type",
"project_type",
type=click.Choice(
[
sdk.ProjectType.REGULAR.value,
sdk.ProjectType.TEMPLATE.value,
]
),
help="Type of the project. Defaults to `regular`.",
)
@click.pass_context
def create_project(ctx: Context, name, owner, description, is_public):
def create_project(
ctx: Context,
name: str,
owner: Optional[str],
description: str,
is_public: bool,
project_type: Optional[str],
):
"""Creates a new empty QFieldCloud project."""

if project_type is not None:
project_type = sdk.ProjectType(project_type)

project = ctx.obj["client"].create_project(
name, owner, description=description, is_public=is_public
name,
owner,
description=description,
is_public=is_public,
project_type=project_type,
)

if ctx.obj["format_json"]:
Expand Down Expand Up @@ -526,6 +556,17 @@ def download_files(
is_flag=True,
help="Whether the project shall be public",
)
@click.option(
"--project-type",
"project_type",
type=click.Choice(
[
sdk.ProjectType.REGULAR.value,
sdk.ProjectType.TEMPLATE.value,
]
),
help="New project type",
)
@click.pass_context
def patch_project(
ctx: Context,
Expand All @@ -534,11 +575,20 @@ def patch_project(
description: Optional[str] = None,
owner: Optional[str] = None,
is_public: Optional[bool] = None,
project_type: Optional[str] = None,
) -> None:
"""Patch the project with new data. Pass only the parameters that shall be changed."""

if project_type is not None:
project_type = sdk.ProjectType(project_type)

project = ctx.obj["client"].patch_project(
project_id, name=name, owner=owner, description=description, is_public=is_public
project_id,
name=name,
owner=owner,
description=description,
is_public=is_public,
project_type=project_type,
)

if ctx.obj["format_json"]:
Expand Down
36 changes: 30 additions & 6 deletions qfieldcloud_sdk/sdk.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,18 @@ class JobTypes(str, Enum):
CREATE_PROJECT = "create_project"


class ProjectType(str, Enum):
"""Represents the type of a project.

Only `REGULAR` and `TEMPLATE` can be set by clients when creating or updating a project.
`SHARED_DATASETS` is managed by the server and is exposed here only so it can be recognized on read.
"""

REGULAR = "regular"
SHARED_DATASETS = "shared_datasets"
TEMPLATE = "template"


class ProjectCollaboratorRole(str, Enum):
"""Defines roles for project collaborators.

Expand Down Expand Up @@ -554,6 +566,7 @@ def create_project(
owner: Optional[str] = None,
description: str = "",
is_public: bool = False,
project_type: Optional[ProjectType] = None,
) -> Dict[str, Any]:
"""Create a new project.

Expand All @@ -562,6 +575,7 @@ def create_project(
owner: The owner of the project. When None, the project will be owned by the currently logged-in user. Defaults to None.
description: A description of the project. Defaults to an empty string.
is_public: Whether the project should be public. Defaults to False.
project_type: The type of the project. Only `ProjectType.REGULAR` and `ProjectType.TEMPLATE` are accepted by the server. When omitted the server defaults to `ProjectType.REGULAR`.

Returns:
A dictionary containing the details of the created project.
Expand All @@ -573,15 +587,20 @@ def create_project(
)
```
"""
data = {
"name": name,
"owner": owner,
"description": description,
"is_public": int(is_public),
}

if project_type is not None:
data["project_type"] = project_type.value

resp = self._request(
"POST",
"projects",
data={
"name": name,
"owner": owner,
"description": description,
"is_public": int(is_public),
},
data=data,
)

return resp.json()
Expand Down Expand Up @@ -611,6 +630,7 @@ def patch_project(
owner: Optional[str] = None,
description: Optional[str] = None,
is_public: Optional[bool] = None,
project_type: Optional[ProjectType] = None,
) -> Dict[str, Any]:
"""Update a project.

Expand All @@ -620,6 +640,7 @@ def patch_project(
owner (str | None, optional): if passed, the new owner. Defaults to None.
description (str, optional): if passed, the new description. Defaults to None.
is_public (bool, optional): if passed, the new public setting. Defaults to None.
project_type (ProjectType | None, optional): if passed, the new project type.

Returns:
Dict[str, Any]: the updated project
Expand All @@ -640,6 +661,9 @@ def patch_project(
if owner:
project_data["owner"] = owner

if project_type is not None:
project_data["project_type"] = project_type.value

if is_public:
project_data["is_public"] = is_public

Expand Down
3 changes: 2 additions & 1 deletion qfieldcloud_sdk/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,13 @@ def format_project_table(projects: List) -> str:
project["id"],
project["owner"] + "/" + project["name"],
project["is_public"],
project["project_type"],
project["description"],
]
)

return format_table(
headers=["ID", "OWNER/NAME", "IS PUBLIC", "DESCRIPTION"],
headers=["ID", "OWNER/NAME", "IS PUBLIC", "PROJECT TYPE", "DESCRIPTION"],
data=data,
)

Expand Down
Loading