Skip to content

Commit

Permalink
refactor(docker): make composition menus responsive: showing spinner,…
Browse files Browse the repository at this point in the history
… etc
  • Loading branch information
sassanh committed Nov 30, 2024
1 parent dc8a42a commit 7bc7344
Show file tree
Hide file tree
Showing 9 changed files with 185 additions and 103 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- feat(docker): support docker compositions and add a way to import `docker-compose.yml` files
- feat(docker): add instructions and icon for docker compositions
- refactor(core): rerender screen when rendering on the display is resumed like when returning from viewfinder to avoid artifacts
- refactor(docker): make composition menus responsive: showing spinner, etc

## Version 1.1.0

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ requires-python = ">=3.11"
keywords = ['ubo', 'ubo-pod', 'raspberry pi', 'rpi', 'home assistance']
dependencies = [
"psutil >=6.0.0",
"ubo-gui >=0.13.8",
"ubo-gui >=0.13.9",
"headless-kivy >=0.12.2",
"pyzbar >=0.1.9",
"sdbus-networkmanager >=2.0.0 ; platform_machine=='aarch64'",
Expand Down
7 changes: 3 additions & 4 deletions ubo_app/menu_app/menu_notification_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from collections.abc import Callable

from ubo_gui.menu.menu_widget import MenuWidget
from ubo_gui.menu.types import PageWidget


class NotificationReference:
Expand Down Expand Up @@ -173,10 +174,8 @@ def run_notification_action(action: NotificationActionItem) -> None:
if notification.value.extra_information:
text = notification.value.extra_information.text

def open_info() -> None:
info_application = NotificationInfo(text=text)

store.dispatch(OpenApplicationAction(application=info_application))
def open_info() -> PageWidget:
return NotificationInfo(text=text)

Check warning on line 178 in ubo_app/menu_app/menu_notification_handler.py

View check run for this annotation

Codecov / codecov/patch

ubo_app/menu_app/menu_notification_handler.py#L177-L178

Added lines #L177 - L178 were not covered by tests

items.append(
NotificationActionItem(
Expand Down
35 changes: 35 additions & 0 deletions ubo_app/services/080-docker/docker_composition.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ def stop_composition(*, id: str) -> None:
"""Stop the composition."""

async def act() -> None:
store.dispatch(

Check warning on line 23 in ubo_app/services/080-docker/docker_composition.py

View check run for this annotation

Codecov / codecov/patch

ubo_app/services/080-docker/docker_composition.py#L22-L23

Added lines #L22 - L23 were not covered by tests
DockerImageSetStatusAction(image=id, status=DockerItemStatus.PROCESSING),
)
stop_process = await asyncio.subprocess.create_subprocess_exec(

Check warning on line 26 in ubo_app/services/080-docker/docker_composition.py

View check run for this annotation

Codecov / codecov/patch

ubo_app/services/080-docker/docker_composition.py#L26

Added line #L26 was not covered by tests
'docker',
'compose',
Expand All @@ -43,6 +46,9 @@ def run_composition(*, id: str) -> None:
"""Run the composition."""

async def act() -> None:
store.dispatch(

Check warning on line 49 in ubo_app/services/080-docker/docker_composition.py

View check run for this annotation

Codecov / codecov/patch

ubo_app/services/080-docker/docker_composition.py#L48-L49

Added lines #L48 - L49 were not covered by tests
DockerImageSetStatusAction(image=id, status=DockerItemStatus.PROCESSING),
)
run_process = await asyncio.subprocess.create_subprocess_exec(

Check warning on line 52 in ubo_app/services/080-docker/docker_composition.py

View check run for this annotation

Codecov / codecov/patch

ubo_app/services/080-docker/docker_composition.py#L52

Added line #L52 was not covered by tests
'docker',
'compose',
Expand All @@ -63,7 +69,36 @@ async def act() -> None:
create_task(act())

Check warning on line 69 in ubo_app/services/080-docker/docker_composition.py

View check run for this annotation

Codecov / codecov/patch

ubo_app/services/080-docker/docker_composition.py#L69

Added line #L69 was not covered by tests


def pull_composition(*, id: str) -> None:
"""Pull the composition images."""

async def act() -> None:
store.dispatch(

Check warning on line 76 in ubo_app/services/080-docker/docker_composition.py

View check run for this annotation

Codecov / codecov/patch

ubo_app/services/080-docker/docker_composition.py#L75-L76

Added lines #L75 - L76 were not covered by tests
DockerImageSetStatusAction(image=id, status=DockerItemStatus.FETCHING),
)
run_process = await asyncio.subprocess.create_subprocess_exec(

Check warning on line 79 in ubo_app/services/080-docker/docker_composition.py

View check run for this annotation

Codecov / codecov/patch

ubo_app/services/080-docker/docker_composition.py#L79

Added line #L79 was not covered by tests
'docker',
'compose',
'pull',
cwd=COMPOSITIONS_PATH / id,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
await run_process.wait()
await log_async_process(

Check warning on line 88 in ubo_app/services/080-docker/docker_composition.py

View check run for this annotation

Codecov / codecov/patch

ubo_app/services/080-docker/docker_composition.py#L87-L88

Added lines #L87 - L88 were not covered by tests
run_process,
title='Docker Composition Error',
message='Failed to run composition.',
)
await check_composition(id=id)

Check warning on line 93 in ubo_app/services/080-docker/docker_composition.py

View check run for this annotation

Codecov / codecov/patch

ubo_app/services/080-docker/docker_composition.py#L93

Added line #L93 was not covered by tests

create_task(act())

Check warning on line 95 in ubo_app/services/080-docker/docker_composition.py

View check run for this annotation

Codecov / codecov/patch

ubo_app/services/080-docker/docker_composition.py#L95

Added line #L95 was not covered by tests


async def _release_composition(id: str) -> None:
store.dispatch(

Check warning on line 99 in ubo_app/services/080-docker/docker_composition.py

View check run for this annotation

Codecov / codecov/patch

ubo_app/services/080-docker/docker_composition.py#L99

Added line #L99 was not covered by tests
DockerImageSetStatusAction(image=id, status=DockerItemStatus.PROCESSING),
)
check_process = await asyncio.subprocess.create_subprocess_exec(

Check warning on line 102 in ubo_app/services/080-docker/docker_composition.py

View check run for this annotation

Codecov / codecov/patch

ubo_app/services/080-docker/docker_composition.py#L102

Added line #L102 was not covered by tests
'docker',
'compose',
Expand Down
22 changes: 19 additions & 3 deletions ubo_app/services/080-docker/menus.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from docker_composition import (
check_composition,
delete_composition,
pull_composition,
release_composition,
run_composition,
stop_composition,
Expand Down Expand Up @@ -57,7 +58,7 @@


@store.view(lambda state: state.ip.interfaces)
def image_menu(
def image_menu( # noqa: C901
interfaces: Sequence[IpNetworkInterface],
image: ImageState,
) -> HeadedMenu:
Expand Down Expand Up @@ -93,6 +94,17 @@ def action() -> PageWidget:
if image.id.startswith('composition_')
else functools.partial(run_container, image=image),
),
*(
[
ActionItem(
label='Pull Images',
icon='󰇚',
action=functools.partial(pull_composition, id=image.id),
),
]
if image.id.startswith('composition_')
else []
),
ActionItem(
label='Delete Application'
if image.id.startswith('composition_')
Expand Down Expand Up @@ -182,16 +194,19 @@ def action() -> PageWidget:
),
),
)
elif image.status == DockerItemStatus.PROCESSING:
pass

Check warning on line 198 in ubo_app/services/080-docker/menus.py

View check run for this annotation

Codecov / codecov/patch

ubo_app/services/080-docker/menus.py#L197-L198

Added lines #L197 - L198 were not covered by tests

if image.id.startswith('composition_'):
messages = {

Check warning on line 201 in ubo_app/services/080-docker/menus.py

View check run for this annotation

Codecov / codecov/patch

ubo_app/services/080-docker/menus.py#L200-L201

Added lines #L200 - L201 were not covered by tests
DockerItemStatus.NOT_AVAILABLE: 'Need to fetch images',
DockerItemStatus.FETCHING: 'Images is being fetched',
DockerItemStatus.FETCHING: 'Images are being fetched',
DockerItemStatus.AVAILABLE: 'Images are ready but composition is not '
'running',
DockerItemStatus.CREATED: 'Composition is created but not running',
DockerItemStatus.RUNNING: 'Composition is running',
DockerItemStatus.ERROR: 'We have an error, please check the logs',
DockerItemStatus.PROCESSING: 'Waiting...',
}
else:
messages = {

Check warning on line 212 in ubo_app/services/080-docker/menus.py

View check run for this annotation

Codecov / codecov/patch

ubo_app/services/080-docker/menus.py#L212

Added line #L212 was not covered by tests
Expand All @@ -201,14 +216,15 @@ def action() -> PageWidget:
DockerItemStatus.CREATED: 'Container is created but not running',
DockerItemStatus.RUNNING: IMAGES[image.id].note or 'Container is running',
DockerItemStatus.ERROR: 'We have an error, please check the logs',
DockerItemStatus.PROCESSING: 'Waiting...',
}

return HeadedMenu(

Check warning on line 222 in ubo_app/services/080-docker/menus.py

View check run for this annotation

Codecov / codecov/patch

ubo_app/services/080-docker/menus.py#L222

Added line #L222 was not covered by tests
title=f'Docker - {image.label}',
heading=image.label,
sub_heading=messages[image.status],
items=items,
placeholder='Waiting...',
placeholder='',
)


Expand Down
4 changes: 2 additions & 2 deletions ubo_app/services/090-web-ui/reducer.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def reducer(
actions=[
NotificationsAddAction(
notification=Notification(
id='web_ui:pending',
id=f'web_ui:pending:{action.description.id}',
icon='󱋆',
title='Web UI',
content=f'[size=18dp]{action.description.prompt}[/size]',
Expand Down Expand Up @@ -81,7 +81,7 @@ def reducer(
if description.id != action.id
],
),
actions=[NotificationsClearByIdAction(id='web_ui:pending')],
actions=[NotificationsClearByIdAction(id=f'web_ui:pending:{action.id}')],
)

return state
1 change: 1 addition & 0 deletions ubo_app/store/services/docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class DockerItemStatus(StrEnum):
CREATED = auto()
RUNNING = auto()
ERROR = auto()
PROCESSING = auto()


class DockerAction(BaseAction):
Expand Down
4 changes: 2 additions & 2 deletions ubo_app/utils/input.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,8 @@ def handle_cancel(event: CameraStopViewfinderEvent) -> None:
if selected_input_method is InputMethod.CAMERA
else NotificationExtraInformation(
text=f"""\
Web dashboard is served on port {hostname}:{WEB_UI_LISTEN_PORT} and it provides an \
interface for entering this input.""",
Web dashboard is served on port {hostname}.local:{WEB_UI_LISTEN_PORT} and it provides \
an interface for entering this input.""",
),
id=prompt_id,
pattern=pattern,
Expand Down
Loading

0 comments on commit 7bc7344

Please sign in to comment.