fastled 1.2.33__py3-none-any.whl → 1.4.50__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fastled/__init__.py +51 -192
- fastled/__main__.py +14 -0
- fastled/__version__.py +6 -0
- fastled/app.py +124 -27
- fastled/args.py +124 -0
- fastled/assets/localhost-key.pem +28 -0
- fastled/assets/localhost.pem +27 -0
- fastled/cli.py +10 -2
- fastled/cli_test.py +21 -0
- fastled/cli_test_interactive.py +21 -0
- fastled/client_server.py +334 -55
- fastled/compile_server.py +12 -1
- fastled/compile_server_impl.py +115 -42
- fastled/docker_manager.py +392 -69
- fastled/emoji_util.py +27 -0
- fastled/filewatcher.py +100 -8
- fastled/find_good_connection.py +105 -0
- fastled/header_dump.py +63 -0
- fastled/install/__init__.py +1 -0
- fastled/install/examples_manager.py +62 -0
- fastled/install/extension_manager.py +113 -0
- fastled/install/main.py +156 -0
- fastled/install/project_detection.py +167 -0
- fastled/install/test_install.py +373 -0
- fastled/install/vscode_config.py +344 -0
- fastled/interruptible_http.py +148 -0
- fastled/keyboard.py +1 -0
- fastled/keyz.py +84 -0
- fastled/live_client.py +26 -1
- fastled/open_browser.py +133 -89
- fastled/parse_args.py +219 -15
- fastled/playwright/chrome_extension_downloader.py +207 -0
- fastled/playwright/playwright_browser.py +773 -0
- fastled/playwright/resize_tracking.py +127 -0
- fastled/print_filter.py +52 -0
- fastled/project_init.py +20 -13
- fastled/select_sketch_directory.py +142 -17
- fastled/server_flask.py +487 -0
- fastled/server_start.py +21 -0
- fastled/settings.py +53 -4
- fastled/site/build.py +2 -10
- fastled/site/examples.py +10 -0
- fastled/sketch.py +129 -7
- fastled/string_diff.py +218 -9
- fastled/test/examples.py +7 -5
- fastled/types.py +22 -2
- fastled/util.py +78 -0
- fastled/version.py +41 -0
- fastled/web_compile.py +401 -218
- fastled/zip_files.py +76 -0
- {fastled-1.2.33.dist-info → fastled-1.4.50.dist-info}/METADATA +533 -382
- fastled-1.4.50.dist-info/RECORD +60 -0
- {fastled-1.2.33.dist-info → fastled-1.4.50.dist-info}/WHEEL +1 -1
- fastled/open_browser2.py +0 -111
- fastled-1.2.33.dist-info/RECORD +0 -33
- {fastled-1.2.33.dist-info → fastled-1.4.50.dist-info}/entry_points.txt +0 -0
- {fastled-1.2.33.dist-info → fastled-1.4.50.dist-info/licenses}/LICENSE +0 -0
- {fastled-1.2.33.dist-info → fastled-1.4.50.dist-info}/top_level.txt +0 -0
fastled/__init__.py
CHANGED
|
@@ -1,22 +1,17 @@
|
|
|
1
1
|
"""FastLED Wasm Compiler package."""
|
|
2
2
|
|
|
3
|
-
# context
|
|
4
|
-
import shutil
|
|
5
|
-
import subprocess
|
|
6
3
|
from contextlib import contextmanager
|
|
7
4
|
from multiprocessing import Process
|
|
8
5
|
from pathlib import Path
|
|
9
6
|
from typing import Generator
|
|
10
7
|
|
|
8
|
+
from .__version__ import __version__
|
|
11
9
|
from .compile_server import CompileServer
|
|
10
|
+
from .emoji_util import EMO
|
|
12
11
|
from .live_client import LiveClient
|
|
12
|
+
from .settings import DOCKER_FILE, IMAGE_NAME
|
|
13
13
|
from .site.build import build
|
|
14
|
-
from .types import BuildMode, CompileResult, CompileServerError
|
|
15
|
-
|
|
16
|
-
# IMPORTANT! There's a bug in github which will REJECT any version update
|
|
17
|
-
# that has any other change in the repo. Please bump the version as the
|
|
18
|
-
# ONLY change in a commit, or else the pypi update and the release will fail.
|
|
19
|
-
__version__ = "1.2.33"
|
|
14
|
+
from .types import BuildMode, CompileResult, CompileServerError, FileResponse
|
|
20
15
|
|
|
21
16
|
|
|
22
17
|
class Api:
|
|
@@ -45,15 +40,31 @@ class Api:
|
|
|
45
40
|
host: str | CompileServer | None = None,
|
|
46
41
|
build_mode: BuildMode = BuildMode.QUICK,
|
|
47
42
|
profile: bool = False, # When true then profile information will be enabled and included in the zip.
|
|
43
|
+
no_platformio: bool = False,
|
|
48
44
|
) -> CompileResult:
|
|
45
|
+
from fastled.sketch import looks_like_fastled_repo
|
|
49
46
|
from fastled.web_compile import web_compile
|
|
50
47
|
|
|
51
48
|
if isinstance(host, CompileServer):
|
|
52
49
|
host = host.url()
|
|
53
50
|
if isinstance(directory, str):
|
|
54
51
|
directory = Path(directory)
|
|
52
|
+
|
|
53
|
+
# Guard: libfastled compilation requires volume source mapping
|
|
54
|
+
# Only allow libcompile if we're in a FastLED repository
|
|
55
|
+
allow_libcompile = looks_like_fastled_repo(Path(".").resolve())
|
|
56
|
+
if not allow_libcompile:
|
|
57
|
+
print(
|
|
58
|
+
f"{EMO('⚠️', 'WARNING:')} libfastled compilation disabled: not running in FastLED repository"
|
|
59
|
+
)
|
|
60
|
+
|
|
55
61
|
out: CompileResult = web_compile(
|
|
56
|
-
directory,
|
|
62
|
+
directory,
|
|
63
|
+
host,
|
|
64
|
+
build_mode=build_mode,
|
|
65
|
+
profile=profile,
|
|
66
|
+
no_platformio=no_platformio,
|
|
67
|
+
allow_libcompile=allow_libcompile,
|
|
57
68
|
)
|
|
58
69
|
return out
|
|
59
70
|
|
|
@@ -67,6 +78,11 @@ class Api:
|
|
|
67
78
|
keep_running=True,
|
|
68
79
|
build_mode=BuildMode.QUICK,
|
|
69
80
|
profile=False,
|
|
81
|
+
http_port: (
|
|
82
|
+
int | None
|
|
83
|
+
) = None, # None means auto select a free port. -1 means no server.
|
|
84
|
+
no_platformio: bool = False,
|
|
85
|
+
enable_https: bool = True, # Enable HTTPS for the local server
|
|
70
86
|
) -> LiveClient:
|
|
71
87
|
return LiveClient(
|
|
72
88
|
sketch_directory=sketch_directory,
|
|
@@ -77,6 +93,9 @@ class Api:
|
|
|
77
93
|
keep_running=keep_running,
|
|
78
94
|
build_mode=build_mode,
|
|
79
95
|
profile=profile,
|
|
96
|
+
http_port=http_port,
|
|
97
|
+
no_platformio=no_platformio,
|
|
98
|
+
enable_https=enable_https,
|
|
80
99
|
)
|
|
81
100
|
|
|
82
101
|
@staticmethod
|
|
@@ -87,9 +106,9 @@ class Api:
|
|
|
87
106
|
mapped_dir: Path | None = None, # Sketch directory.
|
|
88
107
|
container_name: str | None = None, # Specific docker container name.
|
|
89
108
|
remove_previous: bool = False,
|
|
109
|
+
no_platformio: bool = False,
|
|
90
110
|
) -> CompileServer:
|
|
91
111
|
"""Uses docker to spawn a compile server from the given name."""
|
|
92
|
-
from fastled.compile_server import CompileServer
|
|
93
112
|
|
|
94
113
|
out = CompileServer(
|
|
95
114
|
container_name=container_name,
|
|
@@ -98,6 +117,7 @@ class Api:
|
|
|
98
117
|
mapped_dir=mapped_dir,
|
|
99
118
|
auto_start=auto_start,
|
|
100
119
|
remove_previous=remove_previous,
|
|
120
|
+
no_platformio=no_platformio,
|
|
101
121
|
)
|
|
102
122
|
return out
|
|
103
123
|
|
|
@@ -110,6 +130,7 @@ class Api:
|
|
|
110
130
|
mapped_dir: Path | None = None, # Sketch directory.
|
|
111
131
|
container_name: str | None = None, # Specific docker container name.
|
|
112
132
|
remove_previous=False,
|
|
133
|
+
no_platformio: bool = False,
|
|
113
134
|
) -> Generator[CompileServer, None, None]:
|
|
114
135
|
server = Api.spawn_server(
|
|
115
136
|
interactive=interactive,
|
|
@@ -118,6 +139,7 @@ class Api:
|
|
|
118
139
|
mapped_dir=mapped_dir,
|
|
119
140
|
container_name=container_name,
|
|
120
141
|
remove_previous=remove_previous,
|
|
142
|
+
no_platformio=no_platformio,
|
|
121
143
|
)
|
|
122
144
|
try:
|
|
123
145
|
yield server
|
|
@@ -136,7 +158,9 @@ class Docker:
|
|
|
136
158
|
def is_running() -> bool:
|
|
137
159
|
from fastled.docker_manager import DockerManager
|
|
138
160
|
|
|
139
|
-
|
|
161
|
+
ok: bool
|
|
162
|
+
ok, _ = DockerManager.is_running()
|
|
163
|
+
return ok
|
|
140
164
|
|
|
141
165
|
@staticmethod
|
|
142
166
|
def is_container_running(container_name: str | None = None) -> bool:
|
|
@@ -151,186 +175,10 @@ class Docker:
|
|
|
151
175
|
@staticmethod
|
|
152
176
|
def purge() -> None:
|
|
153
177
|
from fastled.docker_manager import DockerManager
|
|
154
|
-
from fastled.settings import IMAGE_NAME
|
|
155
178
|
|
|
156
179
|
docker_mgr = DockerManager()
|
|
157
180
|
docker_mgr.purge(image_name=IMAGE_NAME)
|
|
158
181
|
|
|
159
|
-
@staticmethod
|
|
160
|
-
def build_from_github(
|
|
161
|
-
url: str = "https://github.com/fastled/fastled",
|
|
162
|
-
output_dir: Path | str = Path(".cache/fastled"),
|
|
163
|
-
) -> str:
|
|
164
|
-
"""Build the FastLED WASM compiler Docker image from a GitHub repository.
|
|
165
|
-
|
|
166
|
-
Args:
|
|
167
|
-
url: GitHub repository URL (default: https://github.com/fastled/fastled)
|
|
168
|
-
output_dir: Directory to clone the repo into (default: .cache/fastled)
|
|
169
|
-
|
|
170
|
-
Returns:
|
|
171
|
-
Container name.
|
|
172
|
-
"""
|
|
173
|
-
|
|
174
|
-
from fastled.docker_manager import DockerManager
|
|
175
|
-
from fastled.settings import CONTAINER_NAME, IMAGE_NAME
|
|
176
|
-
|
|
177
|
-
if isinstance(output_dir, str):
|
|
178
|
-
output_dir = Path(output_dir)
|
|
179
|
-
|
|
180
|
-
# Create output directory if it doesn't exist
|
|
181
|
-
output_dir.mkdir(parents=True, exist_ok=True)
|
|
182
|
-
|
|
183
|
-
git_dir = output_dir / ".git"
|
|
184
|
-
library_properties = output_dir / "library.properties"
|
|
185
|
-
|
|
186
|
-
git_dir_exists = git_dir.exists()
|
|
187
|
-
library_properties_exists = library_properties.exists()
|
|
188
|
-
library_properties_text = (
|
|
189
|
-
library_properties.read_text().strip() if library_properties_exists else ""
|
|
190
|
-
)
|
|
191
|
-
|
|
192
|
-
already_exists = (
|
|
193
|
-
git_dir_exists
|
|
194
|
-
and library_properties_exists
|
|
195
|
-
and "FastLED" in library_properties_text
|
|
196
|
-
)
|
|
197
|
-
if git_dir_exists and not already_exists:
|
|
198
|
-
if ".cache/fastled" in str(output_dir.as_posix()):
|
|
199
|
-
shutil.rmtree(output_dir)
|
|
200
|
-
already_exists = False
|
|
201
|
-
else:
|
|
202
|
-
raise ValueError(
|
|
203
|
-
f"Output directory {output_dir} already exists but does not appear to be a FastLED repository."
|
|
204
|
-
)
|
|
205
|
-
|
|
206
|
-
# Clone or update the repository
|
|
207
|
-
if already_exists:
|
|
208
|
-
print(f"Updating existing repository in {output_dir}")
|
|
209
|
-
# Reset local changes and move HEAD back to handle force pushes
|
|
210
|
-
subprocess.run(
|
|
211
|
-
["git", "reset", "--hard", "HEAD~10"],
|
|
212
|
-
cwd=output_dir,
|
|
213
|
-
check=False,
|
|
214
|
-
capture_output=True, # Suppress output of reset
|
|
215
|
-
)
|
|
216
|
-
subprocess.run(
|
|
217
|
-
["git", "pull", "origin", "master"], cwd=output_dir, check=True
|
|
218
|
-
)
|
|
219
|
-
else:
|
|
220
|
-
print(f"Cloning {url} into {output_dir}")
|
|
221
|
-
subprocess.run(
|
|
222
|
-
["git", "clone", "--depth", "1", url, str(output_dir)], check=True
|
|
223
|
-
)
|
|
224
|
-
|
|
225
|
-
dockerfile_path = (
|
|
226
|
-
output_dir / "src" / "platforms" / "wasm" / "compiler" / "Dockerfile"
|
|
227
|
-
)
|
|
228
|
-
|
|
229
|
-
if not dockerfile_path.exists():
|
|
230
|
-
raise FileNotFoundError(
|
|
231
|
-
f"Dockerfile not found at {dockerfile_path}. "
|
|
232
|
-
"This may not be a valid FastLED repository."
|
|
233
|
-
)
|
|
234
|
-
|
|
235
|
-
docker_mgr = DockerManager()
|
|
236
|
-
|
|
237
|
-
platform_tag = ""
|
|
238
|
-
# if "arm" in docker_mgr.architecture():
|
|
239
|
-
if (
|
|
240
|
-
"arm"
|
|
241
|
-
in subprocess.run(["uname", "-m"], capture_output=True).stdout.decode()
|
|
242
|
-
):
|
|
243
|
-
platform_tag = "-arm64"
|
|
244
|
-
|
|
245
|
-
# Build the image
|
|
246
|
-
docker_mgr.build_image(
|
|
247
|
-
image_name=IMAGE_NAME,
|
|
248
|
-
tag="main",
|
|
249
|
-
dockerfile_path=dockerfile_path,
|
|
250
|
-
build_context=output_dir,
|
|
251
|
-
build_args={"NO_PREWARM": "1"},
|
|
252
|
-
platform_tag=platform_tag,
|
|
253
|
-
)
|
|
254
|
-
|
|
255
|
-
# Run the container and return it
|
|
256
|
-
container = docker_mgr.run_container_detached(
|
|
257
|
-
image_name=IMAGE_NAME,
|
|
258
|
-
tag="main",
|
|
259
|
-
container_name=CONTAINER_NAME,
|
|
260
|
-
command=None, # Use default command from Dockerfile
|
|
261
|
-
volumes=None, # No volumes needed for build
|
|
262
|
-
ports=None, # No ports needed for build
|
|
263
|
-
remove_previous=True, # Remove any existing container
|
|
264
|
-
)
|
|
265
|
-
|
|
266
|
-
return container.name # Todo, create an external docker container api.
|
|
267
|
-
|
|
268
|
-
@staticmethod
|
|
269
|
-
def build_from_fastled_repo(
|
|
270
|
-
project_root: Path | str = Path("."),
|
|
271
|
-
interactive: bool = False,
|
|
272
|
-
sketch_folder: Path | None = None,
|
|
273
|
-
) -> CompileServer:
|
|
274
|
-
"""Build the FastLED WASM compiler Docker image, which will be tagged as "main".
|
|
275
|
-
|
|
276
|
-
Args:
|
|
277
|
-
project_root: Path to the FastLED project root directory
|
|
278
|
-
platform_tag: Optional platform tag (e.g. "-arm64" for ARM builds)
|
|
279
|
-
|
|
280
|
-
Returns:
|
|
281
|
-
The string name of the docker container.
|
|
282
|
-
"""
|
|
283
|
-
from fastled.docker_manager import DockerManager
|
|
284
|
-
from fastled.settings import CONTAINER_NAME, IMAGE_NAME
|
|
285
|
-
|
|
286
|
-
project_root = Path(project_root)
|
|
287
|
-
if interactive:
|
|
288
|
-
if sketch_folder is None:
|
|
289
|
-
sketch_folder = project_root / "examples" / "wasm"
|
|
290
|
-
else:
|
|
291
|
-
if sketch_folder is not None:
|
|
292
|
-
raise ValueError(
|
|
293
|
-
"Cannot specify sketch_folder when not in interactive mode."
|
|
294
|
-
)
|
|
295
|
-
if isinstance(project_root, str):
|
|
296
|
-
project_root = Path(project_root)
|
|
297
|
-
|
|
298
|
-
dockerfile_path = (
|
|
299
|
-
project_root / "src" / "platforms" / "wasm" / "compiler" / "Dockerfile"
|
|
300
|
-
)
|
|
301
|
-
docker_mgr = DockerManager()
|
|
302
|
-
platform_tag = ""
|
|
303
|
-
# if "arm" in docker_mgr.architecture():
|
|
304
|
-
if (
|
|
305
|
-
"arm"
|
|
306
|
-
in subprocess.run(["uname", "-m"], capture_output=True).stdout.decode()
|
|
307
|
-
):
|
|
308
|
-
platform_tag = "-arm64"
|
|
309
|
-
|
|
310
|
-
# if image exists, remove it
|
|
311
|
-
docker_mgr.purge(image_name=IMAGE_NAME)
|
|
312
|
-
|
|
313
|
-
# Build the image
|
|
314
|
-
docker_mgr.build_image(
|
|
315
|
-
image_name=IMAGE_NAME,
|
|
316
|
-
tag="main",
|
|
317
|
-
dockerfile_path=dockerfile_path,
|
|
318
|
-
build_context=project_root,
|
|
319
|
-
build_args={"NO_PREWARM": "1"},
|
|
320
|
-
platform_tag=platform_tag,
|
|
321
|
-
)
|
|
322
|
-
|
|
323
|
-
out: CompileServer = CompileServer(
|
|
324
|
-
container_name=CONTAINER_NAME,
|
|
325
|
-
interactive=interactive,
|
|
326
|
-
auto_updates=False,
|
|
327
|
-
mapped_dir=sketch_folder,
|
|
328
|
-
auto_start=True,
|
|
329
|
-
remove_previous=True,
|
|
330
|
-
)
|
|
331
|
-
|
|
332
|
-
return out
|
|
333
|
-
|
|
334
182
|
|
|
335
183
|
class Tools:
|
|
336
184
|
@staticmethod
|
|
@@ -370,14 +218,23 @@ class Test:
|
|
|
370
218
|
def spawn_http_server(
|
|
371
219
|
directory: Path | str = Path("."),
|
|
372
220
|
port: int | None = None,
|
|
221
|
+
compile_server_port: int | None = None,
|
|
373
222
|
open_browser: bool = True,
|
|
223
|
+
app: bool = False,
|
|
224
|
+
enable_https: bool = False, # Default to HTTP for tests (tests use http:// URLs)
|
|
374
225
|
) -> Process:
|
|
375
|
-
from fastled.open_browser import
|
|
226
|
+
from fastled.open_browser import spawn_http_server
|
|
376
227
|
|
|
228
|
+
compile_server_port = compile_server_port or -1
|
|
377
229
|
if isinstance(directory, str):
|
|
378
230
|
directory = Path(directory)
|
|
379
|
-
proc: Process =
|
|
380
|
-
directory,
|
|
231
|
+
proc: Process = spawn_http_server(
|
|
232
|
+
directory,
|
|
233
|
+
port=port,
|
|
234
|
+
compile_server_port=compile_server_port,
|
|
235
|
+
open_browser=open_browser,
|
|
236
|
+
app=app,
|
|
237
|
+
enable_https=enable_https,
|
|
381
238
|
)
|
|
382
239
|
return proc
|
|
383
240
|
|
|
@@ -385,9 +242,11 @@ class Test:
|
|
|
385
242
|
__all__ = [
|
|
386
243
|
"Api",
|
|
387
244
|
"Test",
|
|
388
|
-
"Build",
|
|
389
245
|
"CompileServer",
|
|
390
246
|
"CompileResult",
|
|
391
247
|
"CompileServerError",
|
|
392
248
|
"BuildMode",
|
|
249
|
+
"FileResponse",
|
|
250
|
+
"DOCKER_FILE",
|
|
251
|
+
"__version__",
|
|
393
252
|
]
|
fastled/__main__.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
FastLED Package Main Entry Point
|
|
4
|
+
Enables running the package as: python -m fastled
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import sys
|
|
8
|
+
|
|
9
|
+
from fastled.cli import main
|
|
10
|
+
|
|
11
|
+
if __name__ == "__main__":
|
|
12
|
+
# Pass execution to the main function from cli.py
|
|
13
|
+
# This enables 'python -m fastled' to work the same as 'fastled' command
|
|
14
|
+
sys.exit(main())
|
fastled/__version__.py
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# IMPORTANT! There's a bug in github which will REJECT any version update
|
|
2
|
+
# that has any other change in the repo. Please bump the version as the
|
|
3
|
+
# ONLY change in a commit, or else the pypi update and the release will fail.
|
|
4
|
+
__version__ = "1.4.50"
|
|
5
|
+
|
|
6
|
+
__version_url_latest__ = "https://raw.githubusercontent.com/zackees/fastled-wasm/refs/heads/main/src/fastled/__version__.py"
|
fastled/app.py
CHANGED
|
@@ -2,18 +2,21 @@
|
|
|
2
2
|
Uses the latest wasm compiler image to compile the FastLED sketch.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import os
|
|
6
6
|
import sys
|
|
7
7
|
import time
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
|
|
10
10
|
from fastled.client_server import run_client_server
|
|
11
11
|
from fastled.compile_server import CompileServer
|
|
12
|
+
from fastled.emoji_util import EMO
|
|
12
13
|
from fastled.filewatcher import file_watcher_set
|
|
13
|
-
from fastled.parse_args import parse_args
|
|
14
|
+
from fastled.parse_args import Args, parse_args
|
|
15
|
+
from fastled.settings import DEFAULT_URL
|
|
16
|
+
from fastled.sketch import find_sketch_directories, looks_like_fastled_repo
|
|
14
17
|
|
|
15
18
|
|
|
16
|
-
def run_server(args:
|
|
19
|
+
def run_server(args: Args) -> int:
|
|
17
20
|
interactive = args.interactive
|
|
18
21
|
auto_update = args.auto_update
|
|
19
22
|
mapped_dir = Path(args.directory).absolute() if args.directory else None
|
|
@@ -25,6 +28,8 @@ def run_server(args: argparse.Namespace) -> int:
|
|
|
25
28
|
auto_updates=auto_update,
|
|
26
29
|
mapped_dir=mapped_dir,
|
|
27
30
|
auto_start=True,
|
|
31
|
+
remove_previous=args.clear,
|
|
32
|
+
no_platformio=args.no_platformio,
|
|
28
33
|
)
|
|
29
34
|
|
|
30
35
|
if not interactive:
|
|
@@ -44,41 +49,129 @@ def run_server(args: argparse.Namespace) -> int:
|
|
|
44
49
|
|
|
45
50
|
|
|
46
51
|
def main() -> int:
|
|
52
|
+
from fastled import __version__
|
|
53
|
+
from fastled.select_sketch_directory import select_sketch_directory
|
|
54
|
+
|
|
47
55
|
args = parse_args()
|
|
56
|
+
|
|
57
|
+
if args.emsdk_headers:
|
|
58
|
+
import httpx
|
|
59
|
+
|
|
60
|
+
out_path = args.emsdk_headers
|
|
61
|
+
base_url = args.web if isinstance(args.web, str) else DEFAULT_URL
|
|
62
|
+
try:
|
|
63
|
+
response = httpx.get(f"{base_url}/headers/emsdk")
|
|
64
|
+
if response.status_code == 200:
|
|
65
|
+
Path(out_path).parent.mkdir(parents=True, exist_ok=True)
|
|
66
|
+
with open(out_path, "wb") as f:
|
|
67
|
+
f.write(response.content)
|
|
68
|
+
print(f"{EMO('✅','SUCCESS:')} EMSDK headers exported to {out_path}")
|
|
69
|
+
return 0
|
|
70
|
+
else:
|
|
71
|
+
print(
|
|
72
|
+
f"{EMO('❌','ERROR:')} Failed to export EMSDK headers: HTTP {response.status_code}"
|
|
73
|
+
)
|
|
74
|
+
return 1
|
|
75
|
+
except KeyboardInterrupt:
|
|
76
|
+
print("\nExiting from main...")
|
|
77
|
+
return 1
|
|
78
|
+
except Exception as e:
|
|
79
|
+
print(f"{EMO('❌','ERROR:')} Exception: {e}")
|
|
80
|
+
return 1
|
|
81
|
+
|
|
82
|
+
# Handle --install command early
|
|
83
|
+
if args.install:
|
|
84
|
+
from fastled.install.main import fastled_install
|
|
85
|
+
|
|
86
|
+
result = fastled_install(
|
|
87
|
+
dry_run=args.dry_run, no_interactive=args.no_interactive
|
|
88
|
+
)
|
|
89
|
+
return 0 if result else 1
|
|
90
|
+
|
|
48
91
|
interactive: bool = args.interactive
|
|
49
|
-
|
|
92
|
+
has_server = args.server
|
|
50
93
|
update: bool = args.update
|
|
51
94
|
build: bool = args.build
|
|
52
95
|
just_compile: bool = args.just_compile
|
|
53
96
|
# directory: Path | None = Path(args.directory).absolute() if args.directory else None
|
|
54
97
|
directory: Path | None = Path(args.directory) if args.directory else None
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
98
|
+
cwd_looks_like_fastled_repo = looks_like_fastled_repo()
|
|
99
|
+
|
|
100
|
+
# now it is safe to print out the version
|
|
101
|
+
print(f"FastLED version: {__version__}")
|
|
102
|
+
|
|
103
|
+
# Print current working directory
|
|
104
|
+
print(f"Current working directory: {os.getcwd()}")
|
|
105
|
+
|
|
106
|
+
# Check if Playwright browsers are installed
|
|
107
|
+
playwright_dir = Path.home() / ".fastled" / "playwright"
|
|
108
|
+
if playwright_dir.exists() and any(playwright_dir.iterdir()):
|
|
109
|
+
print(f"{EMO('🎭', '*')} Playwright browsers available at: {playwright_dir}")
|
|
110
|
+
|
|
111
|
+
# Resolve some of the last interactive arguments
|
|
112
|
+
# 1. If interactive is set and the sketch directory is not given,
|
|
113
|
+
# then prompt the user for a sketch directory.
|
|
114
|
+
# 2. Tell the user they can use --server --interactive to
|
|
115
|
+
# skip this prompt.
|
|
116
|
+
if interactive and cwd_looks_like_fastled_repo and directory is None:
|
|
117
|
+
answer = input(
|
|
118
|
+
"No sketch directory selected, would you like to select one? (y/n): "
|
|
119
|
+
)
|
|
120
|
+
if answer.lower()[:1] == "y" or answer.lower() == "":
|
|
121
|
+
sketch_list: list[Path] = find_sketch_directories()
|
|
122
|
+
if sketch_list:
|
|
123
|
+
maybe_dir: str | None = select_sketch_directory(
|
|
124
|
+
sketch_list, cwd_looks_like_fastled_repo, is_followup=True
|
|
125
|
+
)
|
|
126
|
+
if maybe_dir is not None:
|
|
127
|
+
directory = Path(maybe_dir)
|
|
128
|
+
if not directory.exists():
|
|
129
|
+
print(
|
|
130
|
+
f"Directory {directory} does not exist, entering interactive mode without project mapped in."
|
|
131
|
+
)
|
|
132
|
+
directory = None
|
|
62
133
|
|
|
63
134
|
if update:
|
|
64
135
|
# Force auto_update to ensure update check happens
|
|
65
|
-
compile_server = CompileServer(
|
|
136
|
+
compile_server = CompileServer(
|
|
137
|
+
interactive=False, auto_updates=True, no_platformio=args.no_platformio
|
|
138
|
+
)
|
|
66
139
|
compile_server.stop()
|
|
67
140
|
print("Finished updating.")
|
|
68
141
|
return 0
|
|
69
142
|
|
|
70
143
|
if build:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
144
|
+
print("Building is disabled")
|
|
145
|
+
build = False
|
|
146
|
+
|
|
147
|
+
if interactive:
|
|
148
|
+
# raise NotImplementedError("Building is not yet supported.")
|
|
149
|
+
file_watcher_set(False)
|
|
150
|
+
# project_root = Path(".").absolute()
|
|
151
|
+
# print(f"Building Docker image at {project_root}")
|
|
152
|
+
from fastled import Api
|
|
153
|
+
|
|
154
|
+
server: CompileServer = CompileServer(
|
|
155
|
+
interactive=interactive,
|
|
156
|
+
auto_updates=False,
|
|
157
|
+
mapped_dir=directory,
|
|
158
|
+
auto_start=False,
|
|
159
|
+
remove_previous=args.clear,
|
|
160
|
+
no_platformio=args.no_platformio,
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
server.start(wait_for_startup=False)
|
|
76
164
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
165
|
+
try:
|
|
166
|
+
while server.process_running():
|
|
167
|
+
# wait for ctrl-c
|
|
168
|
+
time.sleep(0.1)
|
|
169
|
+
except KeyboardInterrupt:
|
|
170
|
+
print("\nExiting from server...")
|
|
171
|
+
server.stop()
|
|
172
|
+
return 0
|
|
81
173
|
|
|
174
|
+
try:
|
|
82
175
|
if interactive:
|
|
83
176
|
server.stop()
|
|
84
177
|
return 0
|
|
@@ -90,20 +183,22 @@ def main() -> int:
|
|
|
90
183
|
return 0
|
|
91
184
|
|
|
92
185
|
print("Running server")
|
|
186
|
+
|
|
93
187
|
with Api.live_client(
|
|
94
188
|
auto_updates=False,
|
|
95
189
|
sketch_directory=directory,
|
|
96
190
|
host=server,
|
|
97
191
|
auto_start=True,
|
|
98
192
|
keep_running=not just_compile,
|
|
99
|
-
) as
|
|
100
|
-
|
|
101
|
-
|
|
193
|
+
) as _:
|
|
194
|
+
while True:
|
|
195
|
+
time.sleep(0.2) # wait for user to exit
|
|
102
196
|
except KeyboardInterrupt:
|
|
103
197
|
print("\nExiting from client...")
|
|
198
|
+
server.stop()
|
|
104
199
|
return 1
|
|
105
200
|
|
|
106
|
-
if
|
|
201
|
+
if has_server:
|
|
107
202
|
print("Running in server only mode.")
|
|
108
203
|
return run_server(args)
|
|
109
204
|
else:
|
|
@@ -114,12 +209,14 @@ def main() -> int:
|
|
|
114
209
|
if __name__ == "__main__":
|
|
115
210
|
# Note that the entry point for the exe is in cli.py
|
|
116
211
|
try:
|
|
117
|
-
sys.argv.append("-
|
|
118
|
-
sys.argv.append("
|
|
212
|
+
# sys.argv.append("-i")
|
|
213
|
+
# sys.argv.append("-b")
|
|
214
|
+
# sys.argv.append("examples/wasm")
|
|
119
215
|
# sys.argv.append()
|
|
120
216
|
import os
|
|
121
217
|
|
|
122
218
|
os.chdir("../fastled")
|
|
219
|
+
sys.argv.append("examples/FxWave2d")
|
|
123
220
|
sys.exit(main())
|
|
124
221
|
except KeyboardInterrupt:
|
|
125
222
|
print("\nExiting from main...")
|