From b506c2c9b372e314019b9a4685e98f184dcf8264 Mon Sep 17 00:00:00 2001 From: Eric Froemling Date: Wed, 4 May 2022 20:04:05 -0700 Subject: [PATCH] tidying and lint fixes --- .efrocachemap | 88 +++++++++---------- CHANGELOG.md | 2 +- assets/.asset_manifest_public.json | 2 + assets/Makefile | 2 + src/ballistica/ballistica.cc | 2 +- tools/bacloud | 78 +++-------------- tools/bacommon/bacloud.py | 71 +++++++++++++++ tools/bacommon/net.py | 2 +- tools/batools/build.py | 136 ++++++++++++++++------------- 9 files changed, 210 insertions(+), 173 deletions(-) create mode 100644 tools/bacommon/bacloud.py diff --git a/.efrocachemap b/.efrocachemap index bf8a38e6..2bf0a4b0 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -3971,50 +3971,50 @@ "assets/src/ba_data/python/ba/_generated/__init__.py": "https://files.ballistica.net/cache/ba1/ee/e8/cad05aa531c7faf7ff7b96db7f6e", "assets/src/ba_data/python/ba/_generated/enums.py": "https://files.ballistica.net/cache/ba1/b2/e5/0ee0561e16257a32830645239f34", "ballisticacore-windows/Generic/BallisticaCore.ico": "https://files.ballistica.net/cache/ba1/89/c0/e32c7d2a35dc9aef57cc73b0911a", - "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/38/10/0a2c34f84442f87a9b3f156c827e", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/56/ab/886a1d0b8f056a9475bce24bef78", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/75/7c/3ac039f3e2bc3863a79190df0a20", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9e/53/f2a2a34c718cd879fbcba208990b", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/5d/f1/fbba8e0f2409c8337f9650f97d4b", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/ff/79/3b604eb27337dd6dea930e18a8e9", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/18/53/b23f80dcaf61590a6e0be83e5def", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9a/e8/2869a6771945356753256489edd4", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/73/31/215a9ea8602c9eedfc3b0ec86968", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d9/41/bca103eecac94211a3b0bd37c791", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/41/c2/7d827e1feed6f024265b5da625f5", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/38/8d/dca73da1629d31852bc56f198100", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/19/60/e2624ed2ec3d3caf843dfd9a48d3", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/9b/2f/69481fe386808d71ce83aa3c4bb9", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/71/31/52d11e57daf0eaba4f56ddf2231b", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/0b/a7/72e7b8c1e96d3b6d0781bfdab15c", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/54/39/49c6542bebb875c879cef5b8ca34", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/81/d2/be60a229ae04a7f23f602ccb0b7f", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/28/c2/bb75bdc44b391da37ead4336da35", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/92/1e/30720a710e81e534d5d8b31e3ad5", - "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e9/bc/b9747bc5a17617dac9755df078a4", - "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/89/36/71f0e9e7ea3936f65b910f556f92", - "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ac/b7/5d62ae450fdad94b86cad99c9745", - "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/67/8f/aa0f8d5773f89f12cffa96880246", - "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/9c/f8/ac8ef9466a16d69f173e2850f16e", - "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/82/cc/4ff76cd6bdea37b7c963c2cca10b", - "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c9/fd/4d68490a8241e63902c91b15570b", - "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/24/f0/7c60c093c7bf5395a9b7852a5cfb", - "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/0a/09/13882a2f77a2d541b2c7a88150ca", - "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e1/34/c31c62a060131eb5e595168bc790", - "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/cd/42/0c7e1d35dff80532970383caa071", - "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/5f/0a/87ddb51c6d5c1aec2c3dc82a27e8", - "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a3/57/2199e4ba33a04c7348a2f5b8dc82", - "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/6c/c6/57362d1d7178320bf9dac5fe0285", - "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c5/18/1d172d359e0d33136e09a80b9a4a", - "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e5/2b/64feae0cdcda08fbc1609e5c0e62", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/33/73/bb77f2b20ce21a6dd10cca09854f", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/e1/34/aed137660c10c32d83e76f80da89", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/7d/52/26420283884baedbb01a27b7b047", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/ba/0b/3f781295ba0edd23ab3b7de864e0", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/58/64/3ea3064c4fca680739849870da7f", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/6e/4d/edf21d0067ac2e3dda570c5d0bd9", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/f5/4d/aca2657fecc50d43b1bc2982228d", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/00/26/3c127d5291013970420d11056931", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/62/59/1d88d726a5a1d8300ff9543910f0", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/48/24/e7b9b3c1a082760cfc6db0f10ca3", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1b/a6/92035aea2ab0dd03949256a5349e", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/27/07/1d7e2e0a8f9a2ebdf8cc33e56820", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/53/7a/c90a65dbb653cc1f311d815aac58", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/a1/7d/5c334610fe346280e5c6dc372a57", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f9/8f/941afe4781fddf0bd979fd2fd758", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a8/04/1fe1a6bb38814c83097137fa73da", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/82/13/65edadabda615923ff4d7627853e", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/b3/a2/8b5be76d52e33e3628da19fbc1a9", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1f/e6/8531ec0f9a53326891238cffd702", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/8a/e5/c69c71030ef703a7a0637c7c73a5", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/da/68/acf38798fe82e9ead9844ae53757", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/e4/c6/84d27c2ee2095d6955323bff63f6", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/12/aa/e7201b0067e820d095c8c58db855", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/cf/1c/20e854d1a3cdb9640bfb7770f2f7", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/aa/11/4d3b2e9761e951a9205a913d6842", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/09/ff/8b7133310bbf869f19fc79368ee8", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/56/ec/0e501fe0ba3c0a497795b7bde490", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/47/da/a765bbbc77ae3442500e025c4342", + "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/68/d3/a4b1c6366ad425d34ef196f1c49e", + "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2f/42/aff90e076f427bd20e6925d54641", + "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c3/8b/afafe8e0c5896aee9c6177e3619a", + "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c5/7d/ae70ac9d5162235143cd560934f9", + "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/96/30/3b85c7c4d9af95b1f29899603f71", + "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/31/63/1f22739856a91e9e0c8786f0e5e6", + "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/cb/67/06449e9e5fe93cfa070325619c6f", + "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/de/e4/2ef7d74099133e0fc7272f852fc3", + "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/00/e5/439c0214aec11ee65be93843e623", + "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/37/00/a75ab04600c3934e11644a63d864", + "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/74/8c/06a79d42b719af94e8c634b1480f", + "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/91/b8/ab7e097db2d0f1c1c58c9e37ca27", + "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/97/e5/92ca0edbed82a9b2081db73a6a67", + "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/17/ef/6c0510ef98fa3611b09f359f6018", + "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/be/bc/035279dcad567eb7ad4afefe8ed2", + "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/8f/1a/1349780e52df2d59e9ea46266700", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/7c/29/bd985633e24a27703a80ce7e8cb6", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/a1/69/726b6f61333fffb7862a5c5ad2ad", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/40/fa/425f21d8391bb784eff0e2f84c7a", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/88/7e/b155b80d3f4cf3148d0b3c991a84", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/6d/f6/347590d969e154335b282e8a35aa", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/23/2c/bd8bac99b2dc6232d603d0fd9570", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/27/28/1b0efd8cb83ce3ca96f9612a3112", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/e8/67/cd7f25ef0dbac04538ca3d7bebce", "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/b3/15/7c6d580b3482870b5b058858624c", "src/ballistica/generated/python_embedded/bootstrap.inc": "https://files.ballistica.net/cache/ba1/d3/db/e73d4dcf1280d5f677c3cf8b47c3" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index d2a1cb89..878435cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.6.12 (20565, 2022-04-21) +### 1.6.12 (20567, 2022-05-04) - More internal work on V2 master-server communication ### 1.6.11 (20539, 2022-03-23) diff --git a/assets/.asset_manifest_public.json b/assets/.asset_manifest_public.json index 686637e9..743adf58 100644 --- a/assets/.asset_manifest_public.json +++ b/assets/.asset_manifest_public.json @@ -134,10 +134,12 @@ "ba_data/python/bacommon/__init__.py", "ba_data/python/bacommon/__pycache__/__init__.cpython-39.opt-1.pyc", "ba_data/python/bacommon/__pycache__/assets.cpython-39.opt-1.pyc", + "ba_data/python/bacommon/__pycache__/bacloud.cpython-39.opt-1.pyc", "ba_data/python/bacommon/__pycache__/build.cpython-39.opt-1.pyc", "ba_data/python/bacommon/__pycache__/net.cpython-39.opt-1.pyc", "ba_data/python/bacommon/__pycache__/servermanager.cpython-39.opt-1.pyc", "ba_data/python/bacommon/assets.py", + "ba_data/python/bacommon/bacloud.py", "ba_data/python/bacommon/build.py", "ba_data/python/bacommon/net.py", "ba_data/python/bacommon/servermanager.py", diff --git a/assets/Makefile b/assets/Makefile index 1807925d..b2aab5a7 100644 --- a/assets/Makefile +++ b/assets/Makefile @@ -638,6 +638,7 @@ $(eval $(call make-opt-pyc-target,$(element)))) SCRIPT_TARGETS_PY_PUBLIC_TOOLS = \ build/ba_data/python/bacommon/__init__.py \ build/ba_data/python/bacommon/assets.py \ + build/ba_data/python/bacommon/bacloud.py \ build/ba_data/python/bacommon/build.py \ build/ba_data/python/bacommon/net.py \ build/ba_data/python/bacommon/servermanager.py \ @@ -665,6 +666,7 @@ SCRIPT_TARGETS_PY_PUBLIC_TOOLS = \ SCRIPT_TARGETS_PYC_PUBLIC_TOOLS = \ build/ba_data/python/bacommon/__pycache__/__init__.cpython-39.opt-1.pyc \ build/ba_data/python/bacommon/__pycache__/assets.cpython-39.opt-1.pyc \ + build/ba_data/python/bacommon/__pycache__/bacloud.cpython-39.opt-1.pyc \ build/ba_data/python/bacommon/__pycache__/build.cpython-39.opt-1.pyc \ build/ba_data/python/bacommon/__pycache__/net.cpython-39.opt-1.pyc \ build/ba_data/python/bacommon/__pycache__/servermanager.cpython-39.opt-1.pyc \ diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index 27298b4b..185e529b 100644 --- a/src/ballistica/ballistica.cc +++ b/src/ballistica/ballistica.cc @@ -21,7 +21,7 @@ namespace ballistica { // These are set automatically via script; don't modify them here. -const int kAppBuildNumber = 20565; +const int kAppBuildNumber = 20567; const char* kAppVersion = "1.6.12"; // Our standalone globals. diff --git a/tools/bacloud b/tools/bacloud index 5fd33c2f..f142ed6b 100755 --- a/tools/bacloud +++ b/tools/bacloud @@ -9,6 +9,8 @@ from __future__ import annotations import sys import os +import time +import datetime from pathlib import Path from typing import TYPE_CHECKING from dataclasses import dataclass @@ -20,13 +22,15 @@ import requests from efro.error import CleanError from efro.terminal import Clr +from efro.dataclassio import dataclass_from_json +from bacommon.bacloud import Response if TYPE_CHECKING: - from typing import Optional, BinaryIO + from typing import Optional, BinaryIO, IO # Version is sent to the master-server with all commands. Can be incremented # if we need to change behavior server-side to go along with client changes. -VERSION = 1 +VERSION = 2 TOOL_NAME = 'bacloud' @@ -41,64 +45,8 @@ class StateData: login_token: Optional[str] = None -@dataclass -class Response: - """Response sent from the bacloud server to the client. - - Attributes: - message: If present, client should print this message before any other - response processing (including error handling) occurs. - message_end: end arg for message print() call. - error: If present, client should abort with this error message. - login: If present, a token that should be stored client-side and passed - with subsequent commands. - logout: If True, any existing client-side token should be discarded. - dir_manifest: If present, client should generate a manifest of this dir. - It should be added to end_command args as 'manifest'. - uploads: If present, client should upload the requested files (arg1) - individually to a server command (arg2) with provided args (arg3). - uploads_inline: If present, a list of pathnames that should be base64 - gzipped and uploaded to an 'uploads_inline' dict in end_command args. - This should be limited to relatively small files. - downloads_inline: If present, pathnames mapped to base64 gzipped data to - be written to the client. This should only be used for relatively - small files as they are all included inline as part of the response. - deletes: If present, file paths that should be deleted on the client. - dir_prune_empty: If present, all empty dirs under this one should be - removed. - open_url: If present, url to display to the user. - input_prompt: If present, a line of input is read and placed into - end_command args as 'input'. The first value is the prompt printed - before reading and the second is whether it should be read as a - password (without echoing to the terminal). - end_message: If present, a message that should be printed after all other - response processing is done. - end_message_end: end arg for end_message print() call. - end_command: If present, this command is run with these args at the end - of response processing. - """ - message: Optional[str] = None - message_end: str = '\n' - error: Optional[str] = None - login: Optional[str] = None - logout: bool = False - dir_manifest: Optional[str] = None - uploads: Optional[tuple[list[str], str, dict]] = None - uploads_inline: Optional[list[str]] = None - downloads_inline: Optional[dict[str, str]] = None - deletes: Optional[list[str]] = None - dir_prune_empty: Optional[str] = None - open_url: Optional[str] = None - input_prompt: Optional[tuple[str, bool]] = None - end_message: Optional[str] = None - end_message_end: str = '\n' - end_command: Optional[tuple[str, dict]] = None - - def get_tz_offset_seconds() -> float: """Return the offset between utc and local time in seconds.""" - import time - import datetime tval = time.time() utc_offset = (datetime.datetime.fromtimestamp(tval) - datetime.datetime.utcfromtimestamp(tval)).total_seconds() @@ -229,7 +177,7 @@ class App: def _servercmd(self, cmd: str, data: dict, - files: dict[str, BinaryIO] = None) -> Response: + files: dict[str, IO] = None) -> Response: """Issue a command to the server and get a response.""" response_raw_2 = requests.post( @@ -245,14 +193,9 @@ class App: files=files) response_raw_2.raise_for_status() # Except if anything went wrong. assert isinstance(response_raw_2.content, bytes) - output = json.loads(response_raw_2.content.decode()) - # Create a default Response and fill in only attrs we're aware of. - # (newer server may send us attrs we're unaware of) - response = Response() - for key, val in output.items(): - if hasattr(response, key): - setattr(response, key, val) + response = dataclass_from_json(Response, + response_raw_2.content.decode()) # Handle a few things inline. # (so this functionality is available even to recursive commands, etc.) @@ -262,6 +205,9 @@ class App: if response.error is not None: raise CleanError(response.error) + if response.delay_seconds > 0.0: + time.sleep(response.delay_seconds) + return response def _upload_file(self, filename: str, call: str, args: dict) -> None: diff --git a/tools/bacommon/bacloud.py b/tools/bacommon/bacloud.py new file mode 100644 index 00000000..f22f7fe4 --- /dev/null +++ b/tools/bacommon/bacloud.py @@ -0,0 +1,71 @@ +# Released under the MIT License. See LICENSE for details. +# +"""Functionality related to the bacloud tool.""" + +from __future__ import annotations +from dataclasses import dataclass +from typing import TYPE_CHECKING, Optional + +from efro.dataclassio import ioprepped + +if TYPE_CHECKING: + pass + + +@ioprepped +@dataclass +class Response: + # noinspection PyUnresolvedReferences + """Response sent from the bacloud server to the client. + + Attributes: + message: If present, client should print this message before any other + response processing (including error handling) occurs. + message_end: end arg for message print() call. + error: If present, client should abort with this error message. + delay_seconds: How long to wait before proceeding with remaining + response (can be useful when waiting for server progress in a loop). + login: If present, a token that should be stored client-side and passed + with subsequent commands. + logout: If True, any existing client-side token should be discarded. + dir_manifest: If present, client should generate a manifest of this dir. + It should be added to end_command args as 'manifest'. + uploads: If present, client should upload the requested files (arg1) + individually to a server command (arg2) with provided args (arg3). + uploads_inline: If present, a list of pathnames that should be base64 + gzipped and uploaded to an 'uploads_inline' dict in end_command args. + This should be limited to relatively small files. + downloads_inline: If present, pathnames mapped to base64 gzipped data to + be written to the client. This should only be used for relatively + small files as they are all included inline as part of the response. + deletes: If present, file paths that should be deleted on the client. + dir_prune_empty: If present, all empty dirs under this one should be + removed. + open_url: If present, url to display to the user. + input_prompt: If present, a line of input is read and placed into + end_command args as 'input'. The first value is the prompt printed + before reading and the second is whether it should be read as a + password (without echoing to the terminal). + end_message: If present, a message that should be printed after all other + response processing is done. + end_message_end: end arg for end_message print() call. + end_command: If present, this command is run with these args at the end + of response processing. + """ + message: Optional[str] = None + message_end: str = '\n' + error: Optional[str] = None + delay_seconds: float = 0.0 + login: Optional[str] = None + logout: bool = False + dir_manifest: Optional[str] = None + uploads: Optional[tuple[list[str], str, dict]] = None + uploads_inline: Optional[list[str]] = None + downloads_inline: Optional[dict[str, str]] = None + deletes: Optional[list[str]] = None + dir_prune_empty: Optional[str] = None + open_url: Optional[str] = None + input_prompt: Optional[tuple[str, bool]] = None + end_message: Optional[str] = None + end_message_end: str = '\n' + end_command: Optional[tuple[str, dict]] = None diff --git a/tools/bacommon/net.py b/tools/bacommon/net.py index a7cf78fe..5c48443d 100644 --- a/tools/bacommon/net.py +++ b/tools/bacommon/net.py @@ -17,7 +17,7 @@ if TYPE_CHECKING: @dataclass class ServerNodeEntry: """Information about a specific server.""" - zone: Annotated[str, IOAttrs('r')] # FIXME change to 'z' + zone: Annotated[str, IOAttrs('r')] address: Annotated[str, IOAttrs('a')] port: Annotated[int, IOAttrs('p')] diff --git a/tools/batools/build.py b/tools/batools/build.py index c6ab4cca..8bd3d98a 100644 --- a/tools/batools/build.py +++ b/tools/batools/build.py @@ -551,69 +551,85 @@ def checkenv() -> None: # FIXME: since all of these come from pip now, we should just use # pip --list to check versions on everything instead of doing it ad-hoc. for req in PIP_REQUIREMENTS: - modname = req.modulename - minver = req.minversion - pipname = req.pipname - if modname is None: - assert pipname is not None - if pipname not in pipvers: - raise CleanError( - f'{pipname} (for {PYTHON_BIN}) is required.\n' - f'To install it, try: "{PYTHON_BIN}' - f' -m pip install {pipname}"\n' - f'Alternately, "tools/pcommand install_pip_reqs"' - f' will update all pip requirements.') - if minver is not None: - vnums = pipvers[pipname] - assert len(vnums) == len(minver) - if vnums < minver: + try: + modname = req.modulename + minver = req.minversion + pipname = req.pipname + if modname is None: + assert pipname is not None + if pipname not in pipvers: raise CleanError( - f'{pipname} ver. {_vstr(minver)} or newer' - f' is required; found {_vstr(vnums)}.\n' - f'To upgrade it, try: "{PYTHON_BIN}' - f' -m pip install --upgrade {pipname}".\n' - 'Alternately, "tools/pcommand install_pip_reqs"' - ' will update all pip requirements.') - else: - if pipname is None: - pipname = modname - if minver is not None: - results = subprocess.run( - f'{PYTHON_BIN} -m {modname} --version', - shell=True, - check=False, - capture_output=True) + f'{pipname} (for {PYTHON_BIN}) is required.\n' + f'To install it, try: "{PYTHON_BIN}' + f' -m pip install {pipname}"\n' + f'Alternately, "tools/pcommand install_pip_reqs"' + f' will update all pip requirements.') + if minver is not None: + vnums = pipvers[pipname] + assert len(vnums) == len(minver) + if vnums < minver: + raise CleanError( + f'{pipname} ver. {_vstr(minver)} or newer' + f' is required; found {_vstr(vnums)}.\n' + f'To upgrade it, try: "{PYTHON_BIN}' + f' -m pip install --upgrade {pipname}".\n' + 'Alternately, "tools/pcommand install_pip_reqs"' + ' will update all pip requirements.') else: - results = subprocess.run(f'{PYTHON_BIN} -c "import {modname}"', - shell=True, - check=False, - capture_output=True) - if results.returncode != 0: - raise CleanError( - f'{pipname} (for {PYTHON_BIN}) is required.\n' - f'To install it, try: "{PYTHON_BIN}' - f' -m pip install {pipname}"\n' - f'Alternately, "tools/pcommand install_pip_reqs"' - f' will update all pip requirements.') - if minver is not None: - # Note: some modules such as pytest print - # their version to stderr, so grab both. - verlines = (results.stdout + - results.stderr).decode().splitlines() - if verlines[0].startswith('Cpplint fork'): - verlines = verlines[1:] - ver_line = verlines[0] - assert modname in ver_line - vnums = [int(x) for x in ver_line.split()[-1].split('.')] - assert len(vnums) == len(minver) - if vnums < minver: + if pipname is None: + pipname = modname + if minver is not None: + results = subprocess.run( + f'{PYTHON_BIN} -m {modname} --version', + shell=True, + check=False, + capture_output=True) + else: + results = subprocess.run( + f'{PYTHON_BIN} -c "import {modname}"', + shell=True, + check=False, + capture_output=True) + if results.returncode != 0: raise CleanError( - f'{pipname} ver. {_vstr(minver)} or newer' - f' is required; found {_vstr(vnums)}.\n' - f'To upgrade it, try: "{PYTHON_BIN}' - f' -m pip install --upgrade {pipname}".\n' - 'Alternately, "tools/pcommand install_pip_reqs"' - ' will update all pip requirements.') + f'{pipname} (for {PYTHON_BIN}) is required.\n' + f'To install it, try: "{PYTHON_BIN}' + f' -m pip install {pipname}"\n' + f'Alternately, "tools/pcommand install_pip_reqs"' + f' will update all pip requirements.') + if minver is not None: + # Note: some modules such as pytest print + # their version to stderr, so grab both. + verlines = (results.stdout + + results.stderr).decode().splitlines() + if verlines[0].startswith('Cpplint fork'): + verlines = verlines[1:] + ver_line = verlines[0] + assert modname in ver_line + + # Choking on 'mypy 0.xx (compiled: yes)' + if '(compiled: ' in ver_line: + ver_line = ' '.join(ver_line.split()[:2]) + try: + vnums = [ + int(x) for x in ver_line.split()[-1].split('.') + ] + except Exception: + print(f'ERROR PARSING VER LINE for {req}:' + f' \'{ver_line}\'') + raise + assert len(vnums) == len(minver) + if vnums < minver: + raise CleanError( + f'{pipname} ver. {_vstr(minver)} or newer' + f' is required; found {_vstr(vnums)}.\n' + f'To upgrade it, try: "{PYTHON_BIN}' + f' -m pip install --upgrade {pipname}".\n' + 'Alternately, "tools/pcommand install_pip_reqs"' + ' will update all pip requirements.') + except Exception: + print(f'ERROR CHECKING PIP REQ \'{req}\'') + raise print(f'{Clr.BLD}Environment ok.{Clr.RST}', flush=True)