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
51 changes: 51 additions & 0 deletions qfieldcloud_sdk/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,57 @@ def get_project(ctx: Context, project_id: str) -> None:
log("User does not have access to projects yet.")


@cli.command()
@click.argument("project_id")
@click.pass_context
def get_project_seed(ctx: Context, project_id: str) -> None:
"""Get QFieldCloud project seed data."""

project_seed: Dict[str, Any] = ctx.obj["client"].get_project_seed(project_id)

if ctx.obj["format_json"]:
print_json(project_seed)
else:
if project_seed:
log("Project name: {}".format(project_seed["name"]))
log("Project CRS: {}".format(project_seed["crs"]))
log(
"Project extent: {}".format(
", ".join(map(lambda n: str(n), project_seed["extent"]))
)
)
log(
"Project basemaps: {}".format(len(project_seed["settings"]["basemaps"]))
)
log("Project XLSForm: {}".format(bool(project_seed["settings"]["xlsform"])))
else:
log("User does not have access to projects yet.")


@cli.command()
@click.argument("project_id")
@click.argument("destination_dir")
@click.pass_context
def get_project_seed_xlsform(
ctx: Context,
project_id: str,
destination_dir: str,
) -> None:
"""Get QFieldCloud project seed XLSForm file."""

xlsform_filename = ctx.obj["client"].get_project_seed_xlsform(
project_id, destination_dir
)

if ctx.obj["format_json"]:
print_json(xlsform_filename)
else:
if xlsform_filename:
log(f"XLSForm seed file downloaded to: {xlsform_filename}")
else:
log("No XLSForm seed file found for the project.")


@cli.command()
@click.argument("project_id")
@click.option(
Expand Down
76 changes: 74 additions & 2 deletions qfieldcloud_sdk/sdk.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
import logging
import os
import sys
import requests
import urllib3
import cgi

from enum import Enum
from pathlib import Path
from typing import Any, Callable, Dict, List, Optional, TypedDict, Union, cast
from urllib import parse as urlparse

import requests
import urllib3
from requests.adapters import HTTPAdapter, Retry
from requests_toolbelt.multipart.encoder import MultipartEncoderMonitor

Expand Down Expand Up @@ -76,6 +78,7 @@ class JobTypes(str, Enum):
PACKAGE = "package"
APPLY_DELTAS = "delta_apply"
PROCESS_PROJECTFILE = "process_projectfile"
CREATE_PROJECT = "create_project"


class ProjectCollaboratorRole(str, Enum):
Expand Down Expand Up @@ -399,6 +402,75 @@ def get_project(

return cast(Dict, payload)

def get_project_seed(
self,
project_id: str,
) -> Dict[str, Any]:
"""Get project seed data.

Args:
project_id: the project data to get seed data for.

Returns:
A dictionary containing project seed.

Example:
```python
client.get_project_seed(project_id)
```
"""
payload = self._request_json("GET", f"projects/{project_id}/seed")

return cast(Dict, payload)

def get_project_seed_xlsform(
self,
project_id: str,
destination_dir: str,
) -> str | None:
"""Get project seed XLSForm file content.

Args:
project_id: the project data to get seed XLSForm for.

Returns:
The name of the downloaded XLSForm file.

Example:
```python
client.get_project_seed_xlsform(project_id)
```
"""

resp = self._request("GET", f"projects/{project_id}/seed/xlsform")

if resp.status_code != 200:
return None

content_disposition = resp.headers.get("Content-Disposition", "")

if not content_disposition:
logger.warning(
"Response has no `Content-Disposition` header. Skip download of XLSForm file!"
)

return None

_value, params = cgi.parse_header(content_disposition)
filename = params.get("filename")

if not filename:
logger.warning(
"Response has no filename in `Content-Disposition` header. Skip download of XLSForm file!"
)

return None

path = Path(destination_dir).joinpath(filename)
path.write_bytes(resp.content)

return str(path)

def list_remote_files(
self, project_id: str, skip_metadata: bool = True
) -> List[Dict[str, Any]]:
Expand Down
Loading