Skip to content
Merged
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
101 changes: 89 additions & 12 deletions src/infuse_iot/tools/cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
create_release_diff,
get_application_by_organisation_id_and_application_id,
get_applications_by_organisation_id,
get_diffs_by_organisation_id_and_application_id_and_release_id,
get_release_by_organisation_id_and_application_id_and_release_id,
get_releases_by_organisation_id_and_application_id,
)
from infuse_iot.api_client.api.board import (
Expand Down Expand Up @@ -57,7 +59,8 @@ def run(self):

def client(self):
"""Get API client object ready to use"""
return Client(base_url="https://api.infuse-iot.com").with_headers({"x-api-key": f"Bearer {get_api_key()}"})
bearer = self.args.api_key if self.args.api_key else get_api_key()
return Client(base_url="https://api.infuse-iot.com").with_headers({"x-api-key": f"Bearer {bearer}"})


class Organisations(CloudSubCommand):
Expand Down Expand Up @@ -349,6 +352,8 @@ def add_parser(cls, parser):
info_parser = tool_parser.add_parser("info", help="Display summary of application releases")
info_parser.add_argument("--org", "-o", type=str, required=True, help="Organisation ID")
info_parser.add_argument("--app", "-a", type=lambda x: int(x, 16), required=True, help="Application ID (hex)")
info_parser.add_argument("--rel", "-r", type=str, help="Release ID")
info_parser.add_argument("--coap", action="store_true", help="Display CoAP file information")
info_parser.set_defaults(command_fn=cls.info)

upload_parser = tool_parser.add_parser("upload", help="Upload application release")
Expand Down Expand Up @@ -384,7 +389,64 @@ def list(self, client: Client):
)
)

def info(self, client: Client):
def _info_one(self, client: Client):
application = get_application_by_organisation_id_and_application_id.sync(
client=client,
id=UUID(self.args.org),
application_id=self.args.app,
)
if application is None:
sys.exit("Get application: No response")
elif isinstance(application, models.Error):
sys.exit(f"<{application.code}>: {application.message}")
release = get_release_by_organisation_id_and_application_id_and_release_id.sync(
client=client, id=UUID(self.args.org), application_id=self.args.app, release_id=self.args.rel
)
if release is None:
sys.exit("Get release: No response")
elif isinstance(release, models.Error):
sys.exit(f"<{release.code}>: {release.message}")
diffs = get_diffs_by_organisation_id_and_application_id_and_release_id.sync(
client=client, id=UUID(self.args.org), application_id=self.args.app, release_id=self.args.rel
)
if diffs is None:
sys.exit("Get diffs: No response")
elif isinstance(diffs, models.Error):
sys.exit(f"<{diffs.code}>: {diffs.message}")

version = release.version
version_str = f"{version.major}.{version.minor}.{version.revision}+{version.build_num:08x}"

print(
tabulate(
[
["Application Name", application.name],
["Application Description", application.description],
["Board Target", release.board_target],
["Version", version_str],
],
tablefmt="simple",
)
)
diff_info = []
for diff in diffs:
from_release = get_release_by_organisation_id_and_application_id_and_release_id.sync(
client=client, id=UUID(self.args.org), application_id=self.args.app, release_id=diff.from_release_id
)
if not isinstance(from_release, models.ApplicationRelease):
print(f"Failed to query information about source release {diff.from_release_id}")
continue
from_version = from_release.version
from_version_str = (
f"{from_version.major}.{from_version.minor}.{from_version.revision}+{from_version.build_num:08x}"
)
diff_info.append([from_version_str, diff.file.coap_path, diff.file.len_, diff.file.crc])

if len(diff_info) > 0:
print("~~~ Diffs ~~~")
print(tabulate(diff_info, headers=["From Version", "Path", "Length", "CRC"]))

def _info_all(self, client: Client):
releases = get_releases_by_organisation_id_and_application_id.sync(
client=client, id=UUID(self.args.org), application_id=self.args.app
)
Expand All @@ -398,22 +460,36 @@ def info(self, client: Client):
for release in releases:
version = release.version
version_str = f"{version.major}.{version.minor}.{version.revision}+{version.build_num:08x}"
release_list.append(
[
f"{release.board_target}",
version_str,
f"{release.id}",
info = [
f"{release.board_target}",
version_str,
f"{release.id}",
]
if self.args.coap:
info += [release.file.coap_path, str(release.file.len_), str(release.file.crc)]
else:
info += [
f"{release.file.len_ / 1024:.2f} kB",
str(release.created_at),
]
)
release_list.append(info)
if self.args.coap:
headers = ["Board Target", "Version", "ID", "Path", "Length", "CRC"]
else:
headers = ["Board Target", "Version", "ID", "Full OTA", "Created"]
print(
tabulate(
release_list,
headers=["Board Target", "Version", "ID", "Full OTA", "Created"],
headers=headers,
)
)

def info(self, client: Client):
if self.args.rel:
self._info_one(client)
else:
self._info_all(client)

def upload(self, client: Client):
try:
self._board = UUID(self.args.board) if self.args.board else None
Expand Down Expand Up @@ -465,11 +541,11 @@ def upload(self, client: Client):
client=client, id=self._org, application_id=app_id
)

if application is None:
dialog = f"Application 0x{app_id:08x} does not exist in organisation {self.args.org}, create?"
if application is None or (isinstance(application, models.Error) and application.code == 404):
dialog = f"Application 0x{app_id:08x} does not exist in organisation {self._org_name}, create?"
if not user_confirm(dialog):
return
print(f"Creating application 0x{app_id:08x} in organisation {self.args.org}")
print(f"Creating application 0x{app_id:08x} in organisation {self._org_name}")
description = user_response("Application description:")
body = models.NewApplication(id=app_id, name=name, description=description)
application = create_application.sync(client=client, id=self._org, body=body)
Expand Down Expand Up @@ -574,6 +650,7 @@ class SubCommand(InfuseCommand):

@classmethod
def add_parser(cls, parser):
parser.add_argument("--api-key", type=str, help="Cloud API key to use instead of stored credentials")
subparser = parser.add_subparsers(title="commands", metavar="<command>", required=True)

Organisations.add_parser(subparser)
Expand Down
Loading