From 9cb0bc37d5a76ef0303b8deaadf5beb951ce9efc Mon Sep 17 00:00:00 2001 From: Sassan Haradji Date: Sun, 11 Aug 2024 19:32:13 +0400 Subject: [PATCH] fix(core): use fasteners read-write lock implementation for the persistent store - closes #158 --- .github/workflows/integration_delivery.yml | 4 +- CHANGELOG.md | 1 + poetry.lock | 225 +++++++++--------- pyproject.toml | 1 + .../store-desktop-000.jsonc | 6 +- .../all_services_register/store-rpi-000.jsonc | 6 +- ubo_app/menu_app/menu_notification_handler.py | 2 +- ubo_app/services/000-audio/reducer.py | 16 +- ubo_app/services/000-audio/setup.py | 22 +- ubo_app/services/000-keypad/setup.py | 2 +- ubo_app/services/010-voice/reducer.py | 2 +- ubo_app/services/010-voice/setup.py | 64 ++--- .../pages/create_wireless_connection.py | 2 +- ubo_app/services/030-wifi/setup.py | 32 +-- ubo_app/services/050-lightdm/setup.py | 24 +- ubo_app/services/050-ssh/setup.py | 26 +- ubo_app/services/080-docker/reducer.py | 4 +- ubo_app/services/080-docker/setup.py | 2 +- ubo_app/setup.py | 4 +- ubo_app/store/services/audio.py | 38 +-- ubo_app/store/services/notifications.py | 2 +- ubo_app/store/services/voice.py | 6 +- ubo_app/store/services/wifi.py | 10 +- ubo_app/utils/persistent_store.py | 27 +-- 24 files changed, 248 insertions(+), 280 deletions(-) diff --git a/.github/workflows/integration_delivery.yml b/.github/workflows/integration_delivery.yml index 4acb5179..b05303b7 100644 --- a/.github/workflows/integration_delivery.yml +++ b/.github/workflows/integration_delivery.yml @@ -249,8 +249,8 @@ jobs: steps: - uses: actions/checkout@v4 name: Checkout - with: - lfs: true + # with: TODO: this, it consumes lfs bandwidth and should be used only for releases + # lfs: true - uses: actions/setup-python@v5 name: Setup Python diff --git a/CHANGELOG.md b/CHANGELOG.md index a21c6c1b..bde93502 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - feat(rpi-connect): implement `rpi-connect` under `Remote` menu - closes #139 - fix(core): update manager downloads the latest `install.sh` and runs it to do the update - closes #152 - feat(core): add signal management for ubo_app process - closes #156 +- fix(core): use fasteners read-write lock implementation for the persistent store - closes #158 ## Version 0.15.5 diff --git a/poetry.lock b/poetry.lock index 6b79f529..a1dd7a20 100644 --- a/poetry.lock +++ b/poetry.lock @@ -194,13 +194,13 @@ adafruit-circuitpython-register = "*" [[package]] name = "adafruit-platformdetect" -version = "3.72.1" +version = "3.73.0" description = "Platform detection for use by libraries like Adafruit-Blinka." optional = false python-versions = "*" files = [ - {file = "Adafruit_PlatformDetect-3.72.1-py3-none-any.whl", hash = "sha256:65a0aa5054a4a9a8f7e3d4eec9828815a4e1b02085b3c977975e41f697226fd5"}, - {file = "adafruit_platformdetect-3.72.1.tar.gz", hash = "sha256:a360ccb5fddfe60ce52304bb2d5a5345993df03997e33b7fd2dc65e51c39f02c"}, + {file = "Adafruit_PlatformDetect-3.73.0-py3-none-any.whl", hash = "sha256:5fc80192a154c29dc1e2819e9c435ea7f8af8fe01c328f35e4bfdabb9934a425"}, + {file = "adafruit_platformdetect-3.73.0.tar.gz", hash = "sha256:2309098adc8ff87b3d9a4a5d3aeebe3f7b7f55ab0e13d19eb75ffa865f36fab8"}, ] [[package]] @@ -216,98 +216,98 @@ files = [ [[package]] name = "aiohappyeyeballs" -version = "2.3.4" +version = "2.3.5" description = "Happy Eyeballs for asyncio" optional = false -python-versions = "<4.0,>=3.8" +python-versions = ">=3.8" files = [ - {file = "aiohappyeyeballs-2.3.4-py3-none-any.whl", hash = "sha256:40a16ceffcf1fc9e142fd488123b2e218abc4188cf12ac20c67200e1579baa42"}, - {file = "aiohappyeyeballs-2.3.4.tar.gz", hash = "sha256:7e1ae8399c320a8adec76f6c919ed5ceae6edd4c3672f4d9eae2b27e37c80ff6"}, + {file = "aiohappyeyeballs-2.3.5-py3-none-any.whl", hash = "sha256:4d6dea59215537dbc746e93e779caea8178c866856a721c9c660d7a5a7b8be03"}, + {file = "aiohappyeyeballs-2.3.5.tar.gz", hash = "sha256:6fa48b9f1317254f122a07a131a86b71ca6946ca989ce6326fff54a99a920105"}, ] [[package]] name = "aiohttp" -version = "3.10.1" +version = "3.10.3" description = "Async http client/server framework (asyncio)" optional = false python-versions = ">=3.8" files = [ - {file = "aiohttp-3.10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:47b4c2412960e64d97258f40616efddaebcb34ff664c8a972119ed38fac2a62c"}, - {file = "aiohttp-3.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e7dbf637f87dd315fa1f36aaed8afa929ee2c607454fb7791e74c88a0d94da59"}, - {file = "aiohttp-3.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c8fb76214b5b739ce59e2236a6489d9dc3483649cfd6f563dbf5d8e40dbdd57d"}, - {file = "aiohttp-3.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c577cdcf8f92862363b3d598d971c6a84ed8f0bf824d4cc1ce70c2fb02acb4a"}, - {file = "aiohttp-3.10.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:777e23609899cb230ad2642b4bdf1008890f84968be78de29099a8a86f10b261"}, - {file = "aiohttp-3.10.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b07286a1090483799599a2f72f76ac396993da31f6e08efedb59f40876c144fa"}, - {file = "aiohttp-3.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9db600a86414a9a653e3c1c7f6a2f6a1894ab8f83d11505247bd1b90ad57157"}, - {file = "aiohttp-3.10.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01c3f1eb280008e51965a8d160a108c333136f4a39d46f516c64d2aa2e6a53f2"}, - {file = "aiohttp-3.10.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f5dd109a925fee4c9ac3f6a094900461a2712df41745f5d04782ebcbe6479ccb"}, - {file = "aiohttp-3.10.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:8c81ff4afffef9b1186639506d70ea90888218f5ddfff03870e74ec80bb59970"}, - {file = "aiohttp-3.10.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:2a384dfbe8bfebd203b778a30a712886d147c61943675f4719b56725a8bbe803"}, - {file = "aiohttp-3.10.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:b9fb6508893dc31cfcbb8191ef35abd79751db1d6871b3e2caee83959b4d91eb"}, - {file = "aiohttp-3.10.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:88596384c3bec644a96ae46287bb646d6a23fa6014afe3799156aef42669c6bd"}, - {file = "aiohttp-3.10.1-cp310-cp310-win32.whl", hash = "sha256:68164d43c580c2e8bf8e0eb4960142919d304052ccab92be10250a3a33b53268"}, - {file = "aiohttp-3.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:d6bbe2c90c10382ca96df33b56e2060404a4f0f88673e1e84b44c8952517e5f3"}, - {file = "aiohttp-3.10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f6979b4f20d3e557a867da9d9227de4c156fcdcb348a5848e3e6190fd7feb972"}, - {file = "aiohttp-3.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:03c0c380c83f8a8d4416224aafb88d378376d6f4cadebb56b060688251055cd4"}, - {file = "aiohttp-3.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1c2b104e81b3c3deba7e6f5bc1a9a0e9161c380530479970766a6655b8b77c7c"}, - {file = "aiohttp-3.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b023b68c61ab0cd48bd38416b421464a62c381e32b9dc7b4bdfa2905807452a4"}, - {file = "aiohttp-3.10.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a07c76a82390506ca0eabf57c0540cf5a60c993c442928fe4928472c4c6e5e6"}, - {file = "aiohttp-3.10.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:41d8dab8c64ded1edf117d2a64f353efa096c52b853ef461aebd49abae979f16"}, - {file = "aiohttp-3.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:615348fab1a9ef7d0960a905e83ad39051ae9cb0d2837da739b5d3a7671e497a"}, - {file = "aiohttp-3.10.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:256ee6044214ee9d66d531bb374f065ee94e60667d6bbeaa25ca111fc3997158"}, - {file = "aiohttp-3.10.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b7d5bb926805022508b7ddeaad957f1fce7a8d77532068d7bdb431056dc630cd"}, - {file = "aiohttp-3.10.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:028faf71b338f069077af6315ad54281612705d68889f5d914318cbc2aab0d50"}, - {file = "aiohttp-3.10.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:5c12310d153b27aa630750be44e79313acc4e864c421eb7d2bc6fa3429c41bf8"}, - {file = "aiohttp-3.10.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:de1a91d5faded9054957ed0a9e01b9d632109341942fc123947ced358c5d9009"}, - {file = "aiohttp-3.10.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9c186b270979fb1dee3ababe2d12fb243ed7da08b30abc83ebac3a928a4ddb15"}, - {file = "aiohttp-3.10.1-cp311-cp311-win32.whl", hash = "sha256:4a9ce70f5e00380377aac0e568abd075266ff992be2e271765f7b35d228a990c"}, - {file = "aiohttp-3.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:a77c79bac8d908d839d32c212aef2354d2246eb9deb3e2cb01ffa83fb7a6ea5d"}, - {file = "aiohttp-3.10.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:2212296cdb63b092e295c3e4b4b442e7b7eb41e8a30d0f53c16d5962efed395d"}, - {file = "aiohttp-3.10.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4dcb127ca3eb0a61205818a606393cbb60d93b7afb9accd2fd1e9081cc533144"}, - {file = "aiohttp-3.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb8b79a65332e1a426ccb6290ce0409e1dc16b4daac1cc5761e059127fa3d134"}, - {file = "aiohttp-3.10.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68cc24f707ed9cb961f6ee04020ca01de2c89b2811f3cf3361dc7c96a14bfbcc"}, - {file = "aiohttp-3.10.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9cb54f5725b4b37af12edf6c9e834df59258c82c15a244daa521a065fbb11717"}, - {file = "aiohttp-3.10.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:51d03e948e53b3639ce4d438f3d1d8202898ec6655cadcc09ec99229d4adc2a9"}, - {file = "aiohttp-3.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:786299d719eb5d868f161aeec56d589396b053925b7e0ce36e983d30d0a3e55c"}, - {file = "aiohttp-3.10.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abda4009a30d51d3f06f36bc7411a62b3e647fa6cc935ef667e3e3d3a7dd09b1"}, - {file = "aiohttp-3.10.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:67f7639424c313125213954e93a6229d3a1d386855d70c292a12628f600c7150"}, - {file = "aiohttp-3.10.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:8e5a26d7aac4c0d8414a347da162696eea0629fdce939ada6aedf951abb1d745"}, - {file = "aiohttp-3.10.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:120548d89f14b76a041088b582454d89389370632ee12bf39d919cc5c561d1ca"}, - {file = "aiohttp-3.10.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:f5293726943bdcea24715b121d8c4ae12581441d22623b0e6ab12d07ce85f9c4"}, - {file = "aiohttp-3.10.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1f8605e573ed6c44ec689d94544b2c4bb1390aaa723a8b5a2cc0a5a485987a68"}, - {file = "aiohttp-3.10.1-cp312-cp312-win32.whl", hash = "sha256:e7168782621be4448d90169a60c8b37e9b0926b3b79b6097bc180c0a8a119e73"}, - {file = "aiohttp-3.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:8fbf8c0ded367c5c8eaf585f85ca8dd85ff4d5b73fb8fe1e6ac9e1b5e62e11f7"}, - {file = "aiohttp-3.10.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:54b7f4a20d7cc6bfa4438abbde069d417bb7a119f870975f78a2b99890226d55"}, - {file = "aiohttp-3.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2fa643ca990323db68911b92f3f7a0ca9ae300ae340d0235de87c523601e58d9"}, - {file = "aiohttp-3.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d8311d0d690487359fe2247ec5d2cac9946e70d50dced8c01ce9e72341c21151"}, - {file = "aiohttp-3.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:222821c60b8f6a64c5908cb43d69c0ee978a1188f6a8433d4757d39231b42cdb"}, - {file = "aiohttp-3.10.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e7b55d9ede66af7feb6de87ff277e0ccf6d51c7db74cc39337fe3a0e31b5872d"}, - {file = "aiohttp-3.10.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a95151a5567b3b00368e99e9c5334a919514f60888a6b6d2054fea5e66e527e"}, - {file = "aiohttp-3.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e9e9171d2fe6bfd9d3838a6fe63b1e91b55e0bf726c16edf265536e4eafed19"}, - {file = "aiohttp-3.10.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a57e73f9523e980f6101dc9a83adcd7ac0006ea8bf7937ca3870391c7bb4f8ff"}, - {file = "aiohttp-3.10.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:0df51a3d70a2bfbb9c921619f68d6d02591f24f10e9c76de6f3388c89ed01de6"}, - {file = "aiohttp-3.10.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:b0de63ff0307eac3961b4af74382d30220d4813f36b7aaaf57f063a1243b4214"}, - {file = "aiohttp-3.10.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:8db9b749f589b5af8e4993623dbda6716b2b7a5fcb0fa2277bf3ce4b278c7059"}, - {file = "aiohttp-3.10.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:6b14c19172eb53b63931d3e62a9749d6519f7c121149493e6eefca055fcdb352"}, - {file = "aiohttp-3.10.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5cd57ad998e3038aa87c38fe85c99ed728001bf5dde8eca121cadee06ee3f637"}, - {file = "aiohttp-3.10.1-cp38-cp38-win32.whl", hash = "sha256:df31641e3f02b77eb3c5fb63c0508bee0fc067cf153da0e002ebbb0db0b6d91a"}, - {file = "aiohttp-3.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:93094eba50bc2ad4c40ff4997ead1fdcd41536116f2e7d6cfec9596a8ecb3615"}, - {file = "aiohttp-3.10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:440954ddc6b77257e67170d57b1026aa9545275c33312357472504eef7b4cc0b"}, - {file = "aiohttp-3.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f9f8beed277488a52ee2b459b23c4135e54d6a819eaba2e120e57311015b58e9"}, - {file = "aiohttp-3.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d8a8221a63602008550022aa3a4152ca357e1dde7ab3dd1da7e1925050b56863"}, - {file = "aiohttp-3.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a702bd3663b5cbf3916e84bf332400d24cdb18399f0877ca6b313ce6c08bfb43"}, - {file = "aiohttp-3.10.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1988b370536eb14f0ce7f3a4a5b422ab64c4e255b3f5d7752c5f583dc8c967fc"}, - {file = "aiohttp-3.10.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7ccf1f0a304352c891d124ac1a9dea59b14b2abed1704aaa7689fc90ef9c5be1"}, - {file = "aiohttp-3.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc3ea6ef2a83edad84bbdb5d96e22f587b67c68922cd7b6f9d8f24865e655bcf"}, - {file = "aiohttp-3.10.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:89b47c125ab07f0831803b88aeb12b04c564d5f07a1c1a225d4eb4d2f26e8b5e"}, - {file = "aiohttp-3.10.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:21778552ef3d44aac3278cc6f6d13a6423504fa5f09f2df34bfe489ed9ded7f5"}, - {file = "aiohttp-3.10.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:bde0693073fd5e542e46ea100aa6c1a5d36282dbdbad85b1c3365d5421490a92"}, - {file = "aiohttp-3.10.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:bf66149bb348d8e713f3a8e0b4f5b952094c2948c408e1cfef03b49e86745d60"}, - {file = "aiohttp-3.10.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:587237571a85716d6f71f60d103416c9df7d5acb55d96d3d3ced65f39bff9c0c"}, - {file = "aiohttp-3.10.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:bfe33cba6e127d0b5b417623c9aa621f0a69f304742acdca929a9fdab4593693"}, - {file = "aiohttp-3.10.1-cp39-cp39-win32.whl", hash = "sha256:9fbff00646cf8211b330690eb2fd64b23e1ce5b63a342436c1d1d6951d53d8dd"}, - {file = "aiohttp-3.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:5951c328f9ac42d7bce7a6ded535879bc9ae13032818d036749631fa27777905"}, - {file = "aiohttp-3.10.1.tar.gz", hash = "sha256:8b0d058e4e425d3b45e8ec70d49b402f4d6b21041e674798b1f91ba027c73f28"}, + {file = "aiohttp-3.10.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cc36cbdedf6f259371dbbbcaae5bb0e95b879bc501668ab6306af867577eb5db"}, + {file = "aiohttp-3.10.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:85466b5a695c2a7db13eb2c200af552d13e6a9313d7fa92e4ffe04a2c0ea74c1"}, + {file = "aiohttp-3.10.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:71bb1d97bfe7e6726267cea169fdf5df7658831bb68ec02c9c6b9f3511e108bb"}, + {file = "aiohttp-3.10.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:baec1eb274f78b2de54471fc4c69ecbea4275965eab4b556ef7a7698dee18bf2"}, + {file = "aiohttp-3.10.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:13031e7ec1188274bad243255c328cc3019e36a5a907978501256000d57a7201"}, + {file = "aiohttp-3.10.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2bbc55a964b8eecb341e492ae91c3bd0848324d313e1e71a27e3d96e6ee7e8e8"}, + {file = "aiohttp-3.10.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8cc0564b286b625e673a2615ede60a1704d0cbbf1b24604e28c31ed37dc62aa"}, + {file = "aiohttp-3.10.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f817a54059a4cfbc385a7f51696359c642088710e731e8df80d0607193ed2b73"}, + {file = "aiohttp-3.10.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8542c9e5bcb2bd3115acdf5adc41cda394e7360916197805e7e32b93d821ef93"}, + {file = "aiohttp-3.10.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:671efce3a4a0281060edf9a07a2f7e6230dca3a1cbc61d110eee7753d28405f7"}, + {file = "aiohttp-3.10.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0974f3b5b0132edcec92c3306f858ad4356a63d26b18021d859c9927616ebf27"}, + {file = "aiohttp-3.10.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:44bb159b55926b57812dca1b21c34528e800963ffe130d08b049b2d6b994ada7"}, + {file = "aiohttp-3.10.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:6ae9ae382d1c9617a91647575255ad55a48bfdde34cc2185dd558ce476bf16e9"}, + {file = "aiohttp-3.10.3-cp310-cp310-win32.whl", hash = "sha256:aed12a54d4e1ee647376fa541e1b7621505001f9f939debf51397b9329fd88b9"}, + {file = "aiohttp-3.10.3-cp310-cp310-win_amd64.whl", hash = "sha256:b51aef59370baf7444de1572f7830f59ddbabd04e5292fa4218d02f085f8d299"}, + {file = "aiohttp-3.10.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e021c4c778644e8cdc09487d65564265e6b149896a17d7c0f52e9a088cc44e1b"}, + {file = "aiohttp-3.10.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:24fade6dae446b183e2410a8628b80df9b7a42205c6bfc2eff783cbeedc224a2"}, + {file = "aiohttp-3.10.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bc8e9f15939dacb0e1f2d15f9c41b786051c10472c7a926f5771e99b49a5957f"}, + {file = "aiohttp-3.10.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5a9ec959b5381271c8ec9310aae1713b2aec29efa32e232e5ef7dcca0df0279"}, + {file = "aiohttp-3.10.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2a5d0ea8a6467b15d53b00c4e8ea8811e47c3cc1bdbc62b1aceb3076403d551f"}, + {file = "aiohttp-3.10.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c9ed607dbbdd0d4d39b597e5bf6b0d40d844dfb0ac6a123ed79042ef08c1f87e"}, + {file = "aiohttp-3.10.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3e66d5b506832e56add66af88c288c1d5ba0c38b535a1a59e436b300b57b23e"}, + {file = "aiohttp-3.10.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fda91ad797e4914cca0afa8b6cccd5d2b3569ccc88731be202f6adce39503189"}, + {file = "aiohttp-3.10.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:61ccb867b2f2f53df6598eb2a93329b5eee0b00646ee79ea67d68844747a418e"}, + {file = "aiohttp-3.10.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:6d881353264e6156f215b3cb778c9ac3184f5465c2ece5e6fce82e68946868ef"}, + {file = "aiohttp-3.10.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b031ce229114825f49cec4434fa844ccb5225e266c3e146cb4bdd025a6da52f1"}, + {file = "aiohttp-3.10.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5337cc742a03f9e3213b097abff8781f79de7190bbfaa987bd2b7ceb5bb0bdec"}, + {file = "aiohttp-3.10.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ab3361159fd3dcd0e48bbe804006d5cfb074b382666e6c064112056eb234f1a9"}, + {file = "aiohttp-3.10.3-cp311-cp311-win32.whl", hash = "sha256:05d66203a530209cbe40f102ebaac0b2214aba2a33c075d0bf825987c36f1f0b"}, + {file = "aiohttp-3.10.3-cp311-cp311-win_amd64.whl", hash = "sha256:70b4a4984a70a2322b70e088d654528129783ac1ebbf7dd76627b3bd22db2f17"}, + {file = "aiohttp-3.10.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:166de65e2e4e63357cfa8417cf952a519ac42f1654cb2d43ed76899e2319b1ee"}, + {file = "aiohttp-3.10.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:7084876352ba3833d5d214e02b32d794e3fd9cf21fdba99cff5acabeb90d9806"}, + {file = "aiohttp-3.10.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d98c604c93403288591d7d6d7d6cc8a63459168f8846aeffd5b3a7f3b3e5e09"}, + {file = "aiohttp-3.10.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d73b073a25a0bb8bf014345374fe2d0f63681ab5da4c22f9d2025ca3e3ea54fc"}, + {file = "aiohttp-3.10.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8da6b48c20ce78f5721068f383e0e113dde034e868f1b2f5ee7cb1e95f91db57"}, + {file = "aiohttp-3.10.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a9dcdccf50284b1b0dc72bc57e5bbd3cc9bf019060dfa0668f63241ccc16aa7"}, + {file = "aiohttp-3.10.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56fb94bae2be58f68d000d046172d8b8e6b1b571eb02ceee5535e9633dcd559c"}, + {file = "aiohttp-3.10.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bf75716377aad2c718cdf66451c5cf02042085d84522aec1f9246d3e4b8641a6"}, + {file = "aiohttp-3.10.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6c51ed03e19c885c8e91f574e4bbe7381793f56f93229731597e4a499ffef2a5"}, + {file = "aiohttp-3.10.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b84857b66fa6510a163bb083c1199d1ee091a40163cfcbbd0642495fed096204"}, + {file = "aiohttp-3.10.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c124b9206b1befe0491f48185fd30a0dd51b0f4e0e7e43ac1236066215aff272"}, + {file = "aiohttp-3.10.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3461d9294941937f07bbbaa6227ba799bc71cc3b22c40222568dc1cca5118f68"}, + {file = "aiohttp-3.10.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:08bd0754d257b2db27d6bab208c74601df6f21bfe4cb2ec7b258ba691aac64b3"}, + {file = "aiohttp-3.10.3-cp312-cp312-win32.whl", hash = "sha256:7f9159ae530297f61a00116771e57516f89a3de6ba33f314402e41560872b50a"}, + {file = "aiohttp-3.10.3-cp312-cp312-win_amd64.whl", hash = "sha256:e1128c5d3a466279cb23c4aa32a0f6cb0e7d2961e74e9e421f90e74f75ec1edf"}, + {file = "aiohttp-3.10.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:d1100e68e70eb72eadba2b932b185ebf0f28fd2f0dbfe576cfa9d9894ef49752"}, + {file = "aiohttp-3.10.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a541414578ff47c0a9b0b8b77381ea86b0c8531ab37fc587572cb662ccd80b88"}, + {file = "aiohttp-3.10.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d5548444ef60bf4c7b19ace21f032fa42d822e516a6940d36579f7bfa8513f9c"}, + {file = "aiohttp-3.10.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ba2e838b5e6a8755ac8297275c9460e729dc1522b6454aee1766c6de6d56e5e"}, + {file = "aiohttp-3.10.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:48665433bb59144aaf502c324694bec25867eb6630fcd831f7a893ca473fcde4"}, + {file = "aiohttp-3.10.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bac352fceed158620ce2d701ad39d4c1c76d114255a7c530e057e2b9f55bdf9f"}, + {file = "aiohttp-3.10.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b0f670502100cdc567188c49415bebba947eb3edaa2028e1a50dd81bd13363f"}, + {file = "aiohttp-3.10.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43b09f38a67679e32d380fe512189ccb0b25e15afc79b23fbd5b5e48e4fc8fd9"}, + {file = "aiohttp-3.10.3-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:cd788602e239ace64f257d1c9d39898ca65525583f0fbf0988bcba19418fe93f"}, + {file = "aiohttp-3.10.3-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:214277dcb07ab3875f17ee1c777d446dcce75bea85846849cc9d139ab8f5081f"}, + {file = "aiohttp-3.10.3-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:32007fdcaab789689c2ecaaf4b71f8e37bf012a15cd02c0a9db8c4d0e7989fa8"}, + {file = "aiohttp-3.10.3-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:123e5819bfe1b87204575515cf448ab3bf1489cdeb3b61012bde716cda5853e7"}, + {file = "aiohttp-3.10.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:812121a201f0c02491a5db335a737b4113151926a79ae9ed1a9f41ea225c0e3f"}, + {file = "aiohttp-3.10.3-cp38-cp38-win32.whl", hash = "sha256:b97dc9a17a59f350c0caa453a3cb35671a2ffa3a29a6ef3568b523b9113d84e5"}, + {file = "aiohttp-3.10.3-cp38-cp38-win_amd64.whl", hash = "sha256:3731a73ddc26969d65f90471c635abd4e1546a25299b687e654ea6d2fc052394"}, + {file = "aiohttp-3.10.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38d91b98b4320ffe66efa56cb0f614a05af53b675ce1b8607cdb2ac826a8d58e"}, + {file = "aiohttp-3.10.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9743fa34a10a36ddd448bba8a3adc2a66a1c575c3c2940301bacd6cc896c6bf1"}, + {file = "aiohttp-3.10.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7c126f532caf238031c19d169cfae3c6a59129452c990a6e84d6e7b198a001dc"}, + {file = "aiohttp-3.10.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:926e68438f05703e500b06fe7148ef3013dd6f276de65c68558fa9974eeb59ad"}, + {file = "aiohttp-3.10.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:434b3ab75833accd0b931d11874e206e816f6e6626fd69f643d6a8269cd9166a"}, + {file = "aiohttp-3.10.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d35235a44ec38109b811c3600d15d8383297a8fab8e3dec6147477ec8636712a"}, + {file = "aiohttp-3.10.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59c489661edbd863edb30a8bd69ecb044bd381d1818022bc698ba1b6f80e5dd1"}, + {file = "aiohttp-3.10.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50544fe498c81cb98912afabfc4e4d9d85e89f86238348e3712f7ca6a2f01dab"}, + {file = "aiohttp-3.10.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:09bc79275737d4dc066e0ae2951866bb36d9c6b460cb7564f111cc0427f14844"}, + {file = "aiohttp-3.10.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:af4dbec58e37f5afff4f91cdf235e8e4b0bd0127a2a4fd1040e2cad3369d2f06"}, + {file = "aiohttp-3.10.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b22cae3c9dd55a6b4c48c63081d31c00fc11fa9db1a20c8a50ee38c1a29539d2"}, + {file = "aiohttp-3.10.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ba562736d3fbfe9241dad46c1a8994478d4a0e50796d80e29d50cabe8fbfcc3f"}, + {file = "aiohttp-3.10.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f25d6c4e82d7489be84f2b1c8212fafc021b3731abdb61a563c90e37cced3a21"}, + {file = "aiohttp-3.10.3-cp39-cp39-win32.whl", hash = "sha256:b69d832e5f5fa15b1b6b2c8eb6a9fd2c0ec1fd7729cb4322ed27771afc9fc2ac"}, + {file = "aiohttp-3.10.3-cp39-cp39-win_amd64.whl", hash = "sha256:673bb6e3249dc8825df1105f6ef74e2eab779b7ff78e96c15cadb78b04a83752"}, + {file = "aiohttp-3.10.3.tar.gz", hash = "sha256:21650e7032cc2d31fc23d353d7123e771354f2a3d5b05a5647fc30fea214e696"}, ] [package.dependencies] @@ -695,6 +695,17 @@ files = [ [package.extras] tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] +[[package]] +name = "fasteners" +version = "0.19" +description = "A python package that provides useful locks" +optional = false +python-versions = ">=3.6" +files = [ + {file = "fasteners-0.19-py3-none-any.whl", hash = "sha256:758819cb5d94cdedf4e836988b74de396ceacb8e2794d21f82d131fd9ee77237"}, + {file = "fasteners-0.19.tar.gz", hash = "sha256:b4f37c3ac52d8a445af3a66bce57b33b5e90b97c696b7b984f530cf8f0ded09c"}, +] + [[package]] name = "flatbuffers" version = "24.3.25" @@ -1603,13 +1614,13 @@ files = [ [[package]] name = "pyright" -version = "1.1.374" +version = "1.1.375" description = "Command line wrapper for pyright" optional = false python-versions = ">=3.7" files = [ - {file = "pyright-1.1.374-py3-none-any.whl", hash = "sha256:55752bcf7a3646d293cd76710a983b71e16f6128aab2d42468e6eb7e46c0a70d"}, - {file = "pyright-1.1.374.tar.gz", hash = "sha256:d01b2daf864ba5e0362e56b844984865970d7204158e61eb685e2dab7804cb82"}, + {file = "pyright-1.1.375-py3-none-any.whl", hash = "sha256:4c5e27eddeaee8b41cc3120736a1dda6ae120edf8523bb2446b6073a52f286e3"}, + {file = "pyright-1.1.375.tar.gz", hash = "sha256:7765557b0d6782b2fadabff455da2014476404c9e9214f49977a4e49dec19a0f"}, ] [package.dependencies] @@ -1942,29 +1953,29 @@ files = [ [[package]] name = "ruff" -version = "0.5.6" +version = "0.5.7" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.5.6-py3-none-linux_armv6l.whl", hash = "sha256:a0ef5930799a05522985b9cec8290b185952f3fcd86c1772c3bdbd732667fdcd"}, - {file = "ruff-0.5.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b652dc14f6ef5d1552821e006f747802cc32d98d5509349e168f6bf0ee9f8f42"}, - {file = "ruff-0.5.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:80521b88d26a45e871f31e4b88938fd87db7011bb961d8afd2664982dfc3641a"}, - {file = "ruff-0.5.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9bc8f328a9f1309ae80e4d392836e7dbc77303b38ed4a7112699e63d3b066ab"}, - {file = "ruff-0.5.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4d394940f61f7720ad371ddedf14722ee1d6250fd8d020f5ea5a86e7be217daf"}, - {file = "ruff-0.5.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:111a99cdb02f69ddb2571e2756e017a1496c2c3a2aeefe7b988ddab38b416d36"}, - {file = "ruff-0.5.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:e395daba77a79f6dc0d07311f94cc0560375ca20c06f354c7c99af3bf4560c5d"}, - {file = "ruff-0.5.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c476acb43c3c51e3c614a2e878ee1589655fa02dab19fe2db0423a06d6a5b1b6"}, - {file = "ruff-0.5.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2ff8003f5252fd68425fd53d27c1f08b201d7ed714bb31a55c9ac1d4c13e2eb"}, - {file = "ruff-0.5.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c94e084ba3eaa80c2172918c2ca2eb2230c3f15925f4ed8b6297260c6ef179ad"}, - {file = "ruff-0.5.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1f77c1c3aa0669fb230b06fb24ffa3e879391a3ba3f15e3d633a752da5a3e670"}, - {file = "ruff-0.5.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f908148c93c02873210a52cad75a6eda856b2cbb72250370ce3afef6fb99b1ed"}, - {file = "ruff-0.5.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:563a7ae61ad284187d3071d9041c08019975693ff655438d8d4be26e492760bd"}, - {file = "ruff-0.5.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:94fe60869bfbf0521e04fd62b74cbca21cbc5beb67cbb75ab33fe8c174f54414"}, - {file = "ruff-0.5.6-py3-none-win32.whl", hash = "sha256:e6a584c1de6f8591c2570e171cc7ce482bb983d49c70ddf014393cd39e9dfaed"}, - {file = "ruff-0.5.6-py3-none-win_amd64.whl", hash = "sha256:d7fe7dccb1a89dc66785d7aa0ac283b2269712d8ed19c63af908fdccca5ccc1a"}, - {file = "ruff-0.5.6-py3-none-win_arm64.whl", hash = "sha256:57c6c0dd997b31b536bff49b9eee5ed3194d60605a4427f735eeb1f9c1b8d264"}, - {file = "ruff-0.5.6.tar.gz", hash = "sha256:07c9e3c2a8e1fe377dd460371c3462671a728c981c3205a5217291422209f642"}, + {file = "ruff-0.5.7-py3-none-linux_armv6l.whl", hash = "sha256:548992d342fc404ee2e15a242cdbea4f8e39a52f2e7752d0e4cbe88d2d2f416a"}, + {file = "ruff-0.5.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:00cc8872331055ee017c4f1071a8a31ca0809ccc0657da1d154a1d2abac5c0be"}, + {file = "ruff-0.5.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:eaf3d86a1fdac1aec8a3417a63587d93f906c678bb9ed0b796da7b59c1114a1e"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a01c34400097b06cf8a6e61b35d6d456d5bd1ae6961542de18ec81eaf33b4cb8"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fcc8054f1a717e2213500edaddcf1dbb0abad40d98e1bd9d0ad364f75c763eea"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f70284e73f36558ef51602254451e50dd6cc479f8b6f8413a95fcb5db4a55fc"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:a78ad870ae3c460394fc95437d43deb5c04b5c29297815a2a1de028903f19692"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ccd078c66a8e419475174bfe60a69adb36ce04f8d4e91b006f1329d5cd44bcf"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e31c9bad4ebf8fdb77b59cae75814440731060a09a0e0077d559a556453acbb"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d796327eed8e168164346b769dd9a27a70e0298d667b4ecee6877ce8095ec8e"}, + {file = "ruff-0.5.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4a09ea2c3f7778cc635e7f6edf57d566a8ee8f485f3c4454db7771efb692c499"}, + {file = "ruff-0.5.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a36d8dcf55b3a3bc353270d544fb170d75d2dff41eba5df57b4e0b67a95bb64e"}, + {file = "ruff-0.5.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9369c218f789eefbd1b8d82a8cf25017b523ac47d96b2f531eba73770971c9e5"}, + {file = "ruff-0.5.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b88ca3db7eb377eb24fb7c82840546fb7acef75af4a74bd36e9ceb37a890257e"}, + {file = "ruff-0.5.7-py3-none-win32.whl", hash = "sha256:33d61fc0e902198a3e55719f4be6b375b28f860b09c281e4bdbf783c0566576a"}, + {file = "ruff-0.5.7-py3-none-win_amd64.whl", hash = "sha256:083bbcbe6fadb93cd86709037acc510f86eed5a314203079df174c40bbbca6b3"}, + {file = "ruff-0.5.7-py3-none-win_arm64.whl", hash = "sha256:2dca26154ff9571995107221d0aeaad0e75a77b5a682d6236cf89a58c70b76f4"}, + {file = "ruff-0.5.7.tar.gz", hash = "sha256:8dfc0a458797f5d9fb622dd0efc52d796f23f0a1493a9527f4e49a550ae9a7e5"}, ] [[package]] @@ -2344,4 +2355,4 @@ dev = ["headless-kivy", "headless-kivy"] [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "b3452d36c2b39d746f1abaa96115094d2ff3c7bdc1bd8329043e669672d4d50d" +content-hash = "0f5704475e7a2dc1de0bbccc8b1c4bb02b0e001b628b49cd9b4e804a3cfde9ae" diff --git a/pyproject.toml b/pyproject.toml index 400d645f..e02815c9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,6 +54,7 @@ adafruit-circuitpython-veml7700 = "^1.1.22" # RPi dependencies rpi-lgpio = { version = "^0.6", markers = "platform_machine=='aarch64'" } piper-tts = { version = "^1.2.0", markers = "sys_platform=='linux'" } +fasteners = "^0.19" [tool.poetry.group.dev] optional = true diff --git a/tests/integration/results/test_services/all_services_register/store-desktop-000.jsonc b/tests/integration/results/test_services/all_services_register/store-desktop-000.jsonc index 5a928049..c9964ae0 100644 --- a/tests/integration/results/test_services/all_services_register/store-desktop-000.jsonc +++ b/tests/integration/results/test_services/all_services_register/store-desktop-000.jsonc @@ -383,7 +383,7 @@ "icon": "󰄱", "is_short": false, "key": null, - "label": "Orca", + "label": "Picovoice", "opacity": null, "progress": null } @@ -403,7 +403,7 @@ "icon": "󰔊", "is_short": false, "key": null, - "label": "Orca Settings", + "label": "Picovoice Settings", "opacity": null, "progress": null, "sub_menu": { @@ -428,7 +428,7 @@ ], "placeholder": null, "sub_heading": "Set the access key\nCurrent value: Fake", - "title": "Orca Settings" + "title": "Picovoice Settings" } } ], diff --git a/tests/integration/results/test_services/all_services_register/store-rpi-000.jsonc b/tests/integration/results/test_services/all_services_register/store-rpi-000.jsonc index 6b84745b..305918e0 100644 --- a/tests/integration/results/test_services/all_services_register/store-rpi-000.jsonc +++ b/tests/integration/results/test_services/all_services_register/store-rpi-000.jsonc @@ -383,7 +383,7 @@ "icon": "󰄱", "is_short": false, "key": null, - "label": "Orca", + "label": "Picovoice", "opacity": null, "progress": null } @@ -403,7 +403,7 @@ "icon": "󰔊", "is_short": false, "key": null, - "label": "Orca Settings", + "label": "Picovoice Settings", "opacity": null, "progress": null, "sub_menu": { @@ -428,7 +428,7 @@ ], "placeholder": null, "sub_heading": "Set the access key\nCurrent value: Fake", - "title": "Orca Settings" + "title": "Picovoice Settings" } } ], diff --git a/ubo_app/menu_app/menu_notification_handler.py b/ubo_app/menu_app/menu_notification_handler.py index b78f3cf8..6054152f 100644 --- a/ubo_app/menu_app/menu_notification_handler.py +++ b/ubo_app/menu_app/menu_notification_handler.py @@ -67,7 +67,7 @@ def dismiss(_: object = None) -> None: VoiceReadTextAction( text=notification.extra_information.text, piper_text=notification.extra_information.piper_text, - orca_text=notification.extra_information.orca_text, + picovoice_text=notification.extra_information.picovoice_text, ), ) diff --git a/ubo_app/services/000-audio/reducer.py b/ubo_app/services/000-audio/reducer.py index 2f4bac4d..2dad01e6 100644 --- a/ubo_app/services/000-audio/reducer.py +++ b/ubo_app/services/000-audio/reducer.py @@ -42,12 +42,7 @@ def reducer( if isinstance(action, AudioSetVolumeAction): if action.device == AudioDevice.OUTPUT: - return CompleteReducerResult( - state=replace(state, playback_volume=action.volume), - events=[ - AudioPlayChimeEvent(name=Chime.VOLUME_CHANGE), - ], - ) + return replace(state, playback_volume=action.volume) if action.device == AudioDevice.INPUT: return replace(state, capture_volume=action.volume) elif isinstance(action, AudioChangeVolumeAction): @@ -63,6 +58,7 @@ def reducer( ), ), ], + events=[AudioPlayChimeEvent(name=Chime.VOLUME_CHANGE)], ) if action.device == AudioDevice.INPUT: return replace( @@ -74,13 +70,13 @@ def reducer( ) elif isinstance(action, AudioSetMuteStatusAction): if action.device == AudioDevice.OUTPUT: - return replace(state, is_playback_mute=action.mute) + return replace(state, is_playback_mute=action.is_mute) if action.device == AudioDevice.INPUT: return CompleteReducerResult( - state=replace(state, is_capture_mute=action.mute), + state=replace(state, is_capture_mute=action.is_mute), actions=[ StatusIconsRegisterAction( - icon='󰍭' if action.mute else '󰍬', + icon='󰍭' if action.is_mute else '󰍬', priority=AUDIO_MIC_STATE_ICON_PRIORITY, id=AUDIO_MIC_STATE_ICON_ID, ), @@ -91,7 +87,7 @@ def reducer( state=state, actions=[ AudioSetMuteStatusAction( - mute=not state.is_playback_mute + is_mute=not state.is_playback_mute if action.device == AudioDevice.OUTPUT else not state.is_capture_mute, device=action.device, diff --git a/ubo_app/services/000-audio/setup.py b/ubo_app/services/000-audio/setup.py index bffb88b9..3f0e1e9f 100644 --- a/ubo_app/services/000-audio/setup.py +++ b/ubo_app/services/000-audio/setup.py @@ -35,11 +35,6 @@ def _run_async_in_thread( def init_service() -> None: audio_manager = AudioManager() - register_persistent_store( - 'audio_state', - lambda state: state.audio, - ) - dispatch( StatusIconsRegisterAction( icon='󰍭', @@ -79,3 +74,20 @@ def _(is_mute: bool) -> None: # noqa: FBT001 width=event.width, ), ) + + register_persistent_store( + 'audio_state:playback_volume', + lambda state: state.audio.playback_volume, + ) + register_persistent_store( + 'audio_state:is_playback_mute', + lambda state: state.audio.is_playback_mute, + ) + register_persistent_store( + 'audio_state:capture_volume', + lambda state: state.audio.capture_volume, + ) + register_persistent_store( + 'audio_state:is_capture_mute', + lambda state: state.audio.is_capture_mute, + ) diff --git a/ubo_app/services/000-keypad/setup.py b/ubo_app/services/000-keypad/setup.py index 99eb4a93..fcef9202 100644 --- a/ubo_app/services/000-keypad/setup.py +++ b/ubo_app/services/000-keypad/setup.py @@ -217,7 +217,7 @@ def on_button_event(*, index: int, status: ButtonStatus) -> None: dispatch( AudioSetMuteStatusAction( device=AudioDevice.INPUT, - mute=status == 'pressed', + is_mute=status == 'pressed', ), ) diff --git a/ubo_app/services/010-voice/reducer.py b/ubo_app/services/010-voice/reducer.py index 9119abc4..dffe1ef1 100644 --- a/ubo_app/services/010-voice/reducer.py +++ b/ubo_app/services/010-voice/reducer.py @@ -38,7 +38,7 @@ def reducer( VoiceSynthesizeTextEvent( text=action.text, piper_text=action.piper_text or action.text, - orca_text=action.orca_text or action.text, + picovoice_text=action.picovoice_text or action.text, speech_rate=action.speech_rate, ), ], diff --git a/ubo_app/services/010-voice/setup.py b/ubo_app/services/010-voice/setup.py index 36276f9a..e5d296e6 100644 --- a/ubo_app/services/010-voice/setup.py +++ b/ubo_app/services/010-voice/setup.py @@ -6,9 +6,9 @@ import struct from asyncio import CancelledError from queue import Queue -from threading import Lock from typing import TYPE_CHECKING, Any, cast +import fasteners import pvorca from piper.voice import PiperVoice # pyright: ignore [reportMissingModuleSource] from redux import FinishEvent @@ -36,24 +36,24 @@ class _Context: - orca_instance: pvorca.Orca | None = None + picovoice_instance: pvorca.Orca | None = None piper_voice: PiperVoice | None = None - orca_lock: Lock = Lock() + picovoice_lock = fasteners.ReaderWriterLock() def cleanup(self: _Context) -> None: dispatch(VoiceUpdateAccessKeyStatus(is_access_key_set=False)) - with self.orca_lock: - if self.orca_instance: - self.orca_instance.delete() - self.orca_instance = None + with self.picovoice_lock.write_lock(): + if self.picovoice_instance: + self.picovoice_instance.delete() + self.picovoice_instance = None def set_access_key(self: _Context, access_key: str) -> None: dispatch(VoiceUpdateAccessKeyStatus(is_access_key_set=True)) - with self.orca_lock: + with self.picovoice_lock.write_lock(): if access_key: - if self.orca_instance: - self.orca_instance.delete() - self.orca_instance = pvorca.create(access_key) + if self.picovoice_instance: + self.picovoice_instance.delete() + self.picovoice_instance = pvorca.create(access_key) def load_piper(self: _Context) -> None: self.piper_voice = PiperVoice.load( @@ -94,7 +94,7 @@ def clear_access_key() -> None: @view(lambda state: state.voice.selected_engine) -def _engine(engine: str) -> str: +def _engine(engine: VoiceEngine) -> VoiceEngine: return engine @@ -104,7 +104,7 @@ def _engine(engine: str) -> str: def synthesize_and_play(event: VoiceSynthesizeTextEvent) -> None: """Synthesize the text.""" engine = _engine() - if engine == 'piper': + if engine == VoiceEngine.PIPER: text = event.piper_text if not _context.piper_voice: return @@ -138,25 +138,25 @@ def synthesize_and_play(event: VoiceSynthesizeTextEvent) -> None: ), ) unsubscribe() - elif engine == 'orca': - with _context.orca_lock: - if not _context.orca_instance: + elif engine == VoiceEngine.PICOVOICE: + with _context.picovoice_lock.read_lock(): + if not _context.picovoice_instance: return - rate = _context.orca_instance.sample_rate + rate = _context.picovoice_instance.sample_rate - audio_sequence = _context.orca_instance.synthesize( - text=event.orca_text, + audio_sequence = _context.picovoice_instance.synthesize( + text=event.picovoice_text, speech_rate=event.speech_rate, ) - sample = b''.join(struct.pack('h', sample) for sample in audio_sequence[0]) - dispatch( - AudioPlayAudioAction( - sample=sample, - channels=1, - rate=rate, - width=2, - ), - ) + sample = b''.join(struct.pack('h', sample) for sample in audio_sequence[0]) + dispatch( + AudioPlayAudioAction( + sample=sample, + channels=1, + rate=rate, + width=2, + ), + ) @autorun(lambda state: state.voice.is_access_key_set) @@ -186,7 +186,7 @@ def _menu_sub_heading(_: bool | None) -> str: ENGINE_LABELS = { VoiceEngine.PIPER: 'Piper', - VoiceEngine.ORCA: 'Orca', + VoiceEngine.PICOVOICE: 'Picovoice', } @@ -221,7 +221,7 @@ def _engine_selector() -> None: VoiceReadTextAction( text={ VoiceEngine.PIPER: 'Piper voice engine selected', - VoiceEngine.ORCA: 'Orca voice engine selected', + VoiceEngine.PICOVOICE: 'Picovoice voice engine selected', }[engine], engine=engine, ), @@ -269,10 +269,10 @@ def init_service() -> None: ), ), SubMenuItem( - label='Orca Settings', + label='Picovoice Settings', icon='󰔊', sub_menu=HeadedMenu( - title='Orca Settings', + title='Picovoice Settings', heading='󰔊 Picovoice', sub_heading=_menu_sub_heading, items=_menu_items, diff --git a/ubo_app/services/030-wifi/pages/create_wireless_connection.py b/ubo_app/services/030-wifi/pages/create_wireless_connection.py index e0012f8e..5b843940 100644 --- a/ubo_app/services/030-wifi/pages/create_wireless_connection.py +++ b/ubo_app/services/030-wifi/pages/create_wireless_connection.py @@ -61,7 +61,7 @@ async def create_wireless_connection(self: CreateWirelessConnectionPage) -> None extra_information=NotificationExtraInformation( text='Go to your phone settings, choose QR code and hold it in ' 'front of the camera to scan it.', - orca_text='Go to your phone settings, choose {QR|K Y UW AA R} ' + picovoice_text='Go to your phone settings, choose {QR|K Y UW AA R} ' 'code and hold it in front of the camera to scan it.', ), ) diff --git a/ubo_app/services/030-wifi/setup.py b/ubo_app/services/030-wifi/setup.py index dd05bab5..9d986db8 100644 --- a/ubo_app/services/030-wifi/setup.py +++ b/ubo_app/services/030-wifi/setup.py @@ -1,11 +1,8 @@ # ruff: noqa: D100, D101, D102, D103, D104, D107, N999 from __future__ import annotations -import asyncio - from debouncer import DebounceOptions, debounce from pages import create_wireless_connection, main -from redux import ViewOptions from ubo_gui.constants import INFO_COLOR from wifi_manager import ( get_connections, @@ -19,7 +16,7 @@ RegisterSettingAppAction, SettingsCategory, ) -from ubo_app.store.main import dispatch, subscribe_event, view +from ubo_app.store.main import dispatch, subscribe_event from ubo_app.store.services.notifications import ( Importance, Notification, @@ -35,7 +32,10 @@ WiFiUpdateRequestEvent, ) from ubo_app.utils.async_ import create_task -from ubo_app.utils.persistent_store import register_persistent_store +from ubo_app.utils.persistent_store import ( + read_from_persistent_store, + register_persistent_store, +) @debounce( @@ -70,17 +70,6 @@ async def setup_listeners() -> None: create_task(update_wifi_list()) -@view( - lambda state: (state.ip.is_connected, state.wifi.has_visited_onboarding), - options=ViewOptions(default_value=None), -) -def should_show_onboarding(state: tuple[bool | None, bool]) -> bool | None: - is_connected, has_visited_onboarding = state - if is_connected is None: - return None - return not is_connected and not has_visited_onboarding - - def show_onboarding_notification() -> None: dispatch( NotificationsAddAction( @@ -107,7 +96,7 @@ def show_onboarding_notification() -> None: piper_text='Press middle button to add WiFi network with QR code.\n' 'If you dismiss this, you can always add WiFi network through ' 'Settings menu, by navigating to Network, and then WiFi', - orca_text='Press middle button to add {WiFi|W AY F AY} ' + picovoice_text='Press middle button to add {WiFi|W AY F AY} ' 'network with {QR|K Y UW AA R} code.\n' 'If you dismiss this, you can always add {WiFi|W AY F AY} network ' 'through Settings → Network → {WiFi|W AY F AY}', @@ -115,7 +104,6 @@ def show_onboarding_notification() -> None: color=INFO_COLOR, ), ), - WiFiSetHasVisitedOnboardingAction(has_visited_onboarding=True), ) @@ -138,8 +126,10 @@ async def init_service() -> None: subscribe_event(WiFiUpdateRequestEvent, lambda: create_task(request_scan())) - while should_show_onboarding() is None: - await asyncio.sleep(1) - if should_show_onboarding(): + if not read_from_persistent_store( + key='wifi_has_visited_onboarding', + default=False, + ): logger.info('No internet connection, showing WiFi onboarding.') show_onboarding_notification() + dispatch(WiFiSetHasVisitedOnboardingAction(has_visited_onboarding=True)) diff --git a/ubo_app/services/050-lightdm/setup.py b/ubo_app/services/050-lightdm/setup.py index e8f29b74..b9759e2d 100644 --- a/ubo_app/services/050-lightdm/setup.py +++ b/ubo_app/services/050-lightdm/setup.py @@ -115,12 +115,8 @@ async def check_is_lightdm_enabled() -> None: def open_lightdm_menu() -> Menu: """Open the LightDM menu.""" - create_task( - asyncio.gather( - check_is_lightdm_active(), - check_is_lightdm_enabled(), - ), - ) + create_task(check_is_lightdm_active()) + create_task(check_is_lightdm_enabled()) return HeadlessMenu( title=lightdm_title, @@ -142,16 +138,14 @@ def init_service() -> None: ), ) + create_task(check_is_lightdm_active()) + create_task(check_is_lightdm_enabled()) create_task( - asyncio.gather( - check_is_lightdm_active(), - check_is_lightdm_enabled(), - monitor_unit( - 'lightdm.service', - lambda status: dispatch( - LightDMUpdateStateAction( - is_active=status in ('active', 'activating', 'reloading'), - ), + monitor_unit( + 'lightdm.service', + lambda status: dispatch( + LightDMUpdateStateAction( + is_active=status in ('active', 'activating', 'reloading'), ), ), ), diff --git a/ubo_app/services/050-ssh/setup.py b/ubo_app/services/050-ssh/setup.py index 755d192e..4c7e0b0a 100644 --- a/ubo_app/services/050-ssh/setup.py +++ b/ubo_app/services/050-ssh/setup.py @@ -126,7 +126,7 @@ async def act() -> None: 'Note that in order to make things work for you, we had to ' 'make sure password authentication for ssh server is enabled, ' 'you may want to disable it later.', - orca_text='Make sure to delete it after use.\n' + picovoice_text='Make sure to delete it after use.\n' 'Note that in order to make things work for you, we had to ' 'make sure password authentication for {ssh|EH S EH S EY CH} ' 'server is enabled, you may want to disable it later.', @@ -253,12 +253,8 @@ async def check_is_ssh_enabled() -> None: def open_ssh_menu() -> Menu: """Open the SSH menu.""" - create_task( - asyncio.gather( - check_is_ssh_active(), - check_is_ssh_enabled(), - ), - ) + create_task(check_is_ssh_active()) + create_task(check_is_ssh_enabled()) return HeadlessMenu( title=ssh_title, @@ -280,16 +276,14 @@ def init_service() -> None: ), ) + create_task(check_is_ssh_active()) + create_task(check_is_ssh_enabled()) create_task( - asyncio.gather( - check_is_ssh_active(), - check_is_ssh_enabled(), - monitor_unit( - 'ssh.service', - lambda status: dispatch( - SSHUpdateStateAction( - is_active=status in ('active', 'activating', 'reloading'), - ), + monitor_unit( + 'ssh.service', + lambda status: dispatch( + SSHUpdateStateAction( + is_active=status in ('active', 'activating', 'reloading'), ), ), ), diff --git a/ubo_app/services/080-docker/reducer.py b/ubo_app/services/080-docker/reducer.py index da56cd3b..6adec40a 100644 --- a/ubo_app/services/080-docker/reducer.py +++ b/ubo_app/services/080-docker/reducer.py @@ -179,7 +179,7 @@ class ImageEntry(Immutable): 2. Get the authentication token from the dashboard. 3. Convert it to QR code. 4. Scan QR code to input the token.""", - orca_text="""\ + picovoice_text="""\ Follow these steps: 1. Login to your {ngrok|EH N G EH R AA K} account @@ -196,7 +196,7 @@ class ImageEntry(Immutable): extra_information=NotificationExtraInformation( text='This is the command you would enter when running ngrok. ' 'Refer to ngrok documentation for further information', - orca_text="""\ + picovoice_text="""\ This is the command you would enter when running {ngrok|EH N G EH R AA K}. Refer to {ngrok|EH N G EH R AA K} documentation for further information""", ), diff --git a/ubo_app/services/080-docker/setup.py b/ubo_app/services/080-docker/setup.py index c9c207ea..e92aa76e 100644 --- a/ubo_app/services/080-docker/setup.py +++ b/ubo_app/services/080-docker/setup.py @@ -266,7 +266,7 @@ async def act() -> None: example, format it as docker.ay o pipe johndoe pipe password and then convert this \ text into a QR code. If you omit the service name, docker.ay o will automatically be \ used as the default.""", - orca_text="""To generate your {QR|K Y UW AA R} code for \ + picovoice_text="""To generate your {QR|K Y UW AA R} code for \ login, format your details by separating your service, username, and password with the \ pipe symbol. For example, format it as "docker {.|D AA T} io {.|P AY P} johndoe \ {.|P AY P} password" and then convert this text into a {QR|K Y UW AA R} code. If you \ diff --git a/ubo_app/setup.py b/ubo_app/setup.py index eda7a733..51854349 100644 --- a/ubo_app/setup.py +++ b/ubo_app/setup.py @@ -10,8 +10,6 @@ from fake import Fake from redux import FinishAction -from ubo_app.store.main import dispatch - class _FakeAsyncProcess(Fake): def __init__(self: _FakeAsyncProcess, output: bytes = b'') -> None: @@ -121,6 +119,8 @@ def signal_handler(signum: int, _: object) -> None: signal.signal(signal.SIGINT, signal.SIG_DFL) if signum == signal.SIGINT: logger.info('Exiting gracefully, sending the signal again will force exit!') + from ubo_app.store.main import dispatch + dispatch(FinishAction()) elif signum == signal.SIGTERM: logger.info( diff --git a/ubo_app/store/services/audio.py b/ubo_app/store/services/audio.py index 80b522ba..2af0ff7f 100644 --- a/ubo_app/store/services/audio.py +++ b/ubo_app/store/services/audio.py @@ -29,7 +29,7 @@ class AudioChangeVolumeAction(AudioAction): class AudioSetMuteStatusAction(AudioAction): - mute: bool + is_mute: bool device: AudioDevice @@ -71,37 +71,25 @@ class AudioPlaybackDoneEvent(AudioEvent): class AudioState(Immutable): playback_volume: float = field( default_factory=lambda: read_from_persistent_store( - key='audio_state', - object_type=AudioState, - default=default_audio_state, - ).playback_volume, + 'audio_state:playback_volume', + default=0.5, + ), ) is_playback_mute: bool = field( default_factory=lambda: read_from_persistent_store( - key='audio_state', - object_type=AudioState, - default=default_audio_state, - ).is_playback_mute, + 'audio_state:is_playback_mute', + default=False, + ), ) capture_volume: float = field( default_factory=lambda: read_from_persistent_store( - key='audio_state', - object_type=AudioState, - default=default_audio_state, - ).capture_volume, + 'audio_state:capture_volume', + default=0.5, + ), ) is_capture_mute: bool = field( default_factory=lambda: read_from_persistent_store( - key='audio_state', - object_type=AudioState, - default=default_audio_state, - ).is_capture_mute, + 'audio_state:is_capture_mute', + default=False, + ), ) - - -default_audio_state = AudioState( - playback_volume=0.5, - is_playback_mute=False, - capture_volume=0.5, - is_capture_mute=False, -) diff --git a/ubo_app/store/services/notifications.py b/ubo_app/store/services/notifications.py index 6e2b5032..875a41c6 100644 --- a/ubo_app/store/services/notifications.py +++ b/ubo_app/store/services/notifications.py @@ -85,7 +85,7 @@ class NotificationActionItem(ActionItem): class NotificationExtraInformation(Immutable): text: str piper_text: str | None = None - orca_text: str | None = None + picovoice_text: str | None = None class Notification(Immutable): diff --git a/ubo_app/store/services/voice.py b/ubo_app/store/services/voice.py index 06d8e6e9..5260c748 100644 --- a/ubo_app/store/services/voice.py +++ b/ubo_app/store/services/voice.py @@ -22,7 +22,7 @@ class VoiceUpdateAccessKeyStatus(VoiceAction): class VoiceEngine(StrEnum): PIPER = 'piper' - ORCA = 'orca' + PICOVOICE = 'picovoice' class VoiceSetEngineAction(VoiceAction): @@ -32,7 +32,7 @@ class VoiceSetEngineAction(VoiceAction): class VoiceReadTextAction(VoiceAction): text: str piper_text: str | None = None - orca_text: str | None = None + picovoice_text: str | None = None speech_rate: float | None = None engine: VoiceEngine | None = None @@ -40,7 +40,7 @@ class VoiceReadTextAction(VoiceAction): class VoiceSynthesizeTextEvent(VoiceEvent): text: str piper_text: str - orca_text: str + picovoice_text: str speech_rate: float | None = None diff --git a/ubo_app/store/services/wifi.py b/ubo_app/store/services/wifi.py index 3c9374d0..b65e23ec 100644 --- a/ubo_app/store/services/wifi.py +++ b/ubo_app/store/services/wifi.py @@ -1,15 +1,12 @@ # ruff: noqa: D100, D101, D102, D103, D104, D107 from __future__ import annotations -from dataclasses import field from enum import StrEnum from typing import TYPE_CHECKING from immutable import Immutable from redux import BaseAction, BaseEvent -from ubo_app.utils.persistent_store import read_from_persistent_store - if TYPE_CHECKING: from collections.abc import Sequence @@ -72,9 +69,4 @@ class WiFiState(Immutable): connections: Sequence[WiFiConnection] | None state: GlobalWiFiState current_connection: WiFiConnection | None - has_visited_onboarding: bool = field( - default_factory=lambda: read_from_persistent_store( - key='wifi_has_visited_onboarding', - default=False, - ), - ) + has_visited_onboarding: bool | None = None diff --git a/ubo_app/utils/persistent_store.py b/ubo_app/utils/persistent_store.py index c2e9482a..ab94b930 100644 --- a/ubo_app/utils/persistent_store.py +++ b/ubo_app/utils/persistent_store.py @@ -3,10 +3,10 @@ from __future__ import annotations import json -from asyncio import Lock from pathlib import Path from typing import TYPE_CHECKING, TypeVar, cast, overload +import fasteners from redux import FinishEvent from ubo_app.constants import PERSISTENT_STORE_PATH @@ -18,7 +18,7 @@ T = TypeVar('T') -persistent_store_lock = Lock() +persistent_store_lock = fasteners.ReaderWriterLock() def register_persistent_store( @@ -32,7 +32,7 @@ def register_persistent_store( async def write(value: T) -> None: if value is None: return - async with persistent_store_lock: + with persistent_store_lock.write_lock(): try: current_state = json.loads(Path(PERSISTENT_STORE_PATH).read_text()) except FileNotFoundError: @@ -76,23 +76,12 @@ def read_from_persistent_store( """Read a part of the store from the filesystem.""" from ubo_app.store.main import store - for _ in range(5): - try: + try: + with persistent_store_lock.read_lock(): file_content = Path(PERSISTENT_STORE_PATH).read_text() - current_state = json.loads(file_content) - except FileNotFoundError: - return ( - (None if object_type is None else object_type()) - if default is None - else default - ) - except json.JSONDecodeError: - continue - else: - break - else: - msg = 'Failed to read from the persistent store' - raise RuntimeError(msg) + current_state = json.loads(file_content) + except FileNotFoundError: + current_state = {} value = current_state.get(key) if value is None: return (