fastled 1.1.3__py2.py3-none-any.whl → 1.1.7__py2.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/app.py +25 -71
- fastled/compile_server.py +8 -21
- fastled/sketch.py +55 -0
- fastled/web_compile.py +130 -123
- {fastled-1.1.3.dist-info → fastled-1.1.7.dist-info}/METADATA +6 -1
- {fastled-1.1.3.dist-info → fastled-1.1.7.dist-info}/RECORD +10 -9
- {fastled-1.1.3.dist-info → fastled-1.1.7.dist-info}/LICENSE +0 -0
- {fastled-1.1.3.dist-info → fastled-1.1.7.dist-info}/WHEEL +0 -0
- {fastled-1.1.3.dist-info → fastled-1.1.7.dist-info}/entry_points.txt +0 -0
- {fastled-1.1.3.dist-info → fastled-1.1.7.dist-info}/top_level.txt +0 -0
fastled/app.py
CHANGED
@@ -20,6 +20,7 @@ from fastled.compile_server import CompileServer, looks_like_fastled_repo
|
|
20
20
|
from fastled.docker_manager import DockerManager
|
21
21
|
from fastled.filewatcher import FileChangedNotifier
|
22
22
|
from fastled.open_browser import open_browser_thread
|
23
|
+
from fastled.sketch import looks_like_sketch_directory
|
23
24
|
from fastled.web_compile import web_compile
|
24
25
|
|
25
26
|
machine = platform.machine().lower()
|
@@ -48,7 +49,7 @@ def parse_args() -> argparse.Namespace:
|
|
48
49
|
"directory",
|
49
50
|
type=str,
|
50
51
|
nargs="?",
|
51
|
-
default=
|
52
|
+
default=None,
|
52
53
|
help="Directory containing the FastLED sketch to compile",
|
53
54
|
)
|
54
55
|
parser.add_argument(
|
@@ -56,11 +57,6 @@ def parse_args() -> argparse.Namespace:
|
|
56
57
|
action="store_true",
|
57
58
|
help="Just compile, skip opening the browser and watching for changes.",
|
58
59
|
)
|
59
|
-
parser.add_argument(
|
60
|
-
"--no-auto-clean",
|
61
|
-
action="store_true",
|
62
|
-
help="Big performance gains for compilation, but it's flaky at this time",
|
63
|
-
)
|
64
60
|
parser.add_argument(
|
65
61
|
"--web",
|
66
62
|
"-w",
|
@@ -70,17 +66,6 @@ def parse_args() -> argparse.Namespace:
|
|
70
66
|
const=DEFAULT_URL, # Default value when --web is specified without value
|
71
67
|
help="Use web compiler. Optional URL can be provided (default: https://fastled.onrender.com)",
|
72
68
|
)
|
73
|
-
parser.add_argument(
|
74
|
-
"--reuse",
|
75
|
-
action="store_true",
|
76
|
-
help="Reuse the existing container if it exists. (Not available with --web)",
|
77
|
-
)
|
78
|
-
parser.add_argument(
|
79
|
-
"--exclude",
|
80
|
-
type=str,
|
81
|
-
nargs="+",
|
82
|
-
help="Additional patterns to exclude from file watching (Not available with --web)",
|
83
|
-
)
|
84
69
|
parser.add_argument(
|
85
70
|
"-i",
|
86
71
|
"--interactive",
|
@@ -116,14 +101,18 @@ def parse_args() -> argparse.Namespace:
|
|
116
101
|
)
|
117
102
|
|
118
103
|
args = parser.parse_args()
|
119
|
-
|
120
|
-
|
121
|
-
if args.
|
122
|
-
|
123
|
-
|
124
|
-
if
|
125
|
-
|
126
|
-
|
104
|
+
if args.server and args.web:
|
105
|
+
parser.error("--server and --web are mutually exclusive")
|
106
|
+
if args.directory is None and not args.server:
|
107
|
+
# does current directory look like a sketch?
|
108
|
+
maybe_sketch_dir = Path(os.getcwd())
|
109
|
+
if looks_like_sketch_directory(maybe_sketch_dir):
|
110
|
+
args.directory = str(maybe_sketch_dir)
|
111
|
+
else:
|
112
|
+
print(
|
113
|
+
"\nYou either need to specify a sketch directory or run in --server mode."
|
114
|
+
)
|
115
|
+
sys.exit(1)
|
127
116
|
return args
|
128
117
|
|
129
118
|
|
@@ -194,9 +183,8 @@ def _try_start_server_or_get_url(args: argparse.Namespace) -> str | CompileServe
|
|
194
183
|
return DEFAULT_URL
|
195
184
|
return args.web
|
196
185
|
else:
|
197
|
-
disable_auto_clean = args.no_auto_clean
|
198
186
|
try:
|
199
|
-
compile_server = CompileServer(
|
187
|
+
compile_server = CompileServer()
|
200
188
|
print("Waiting for the local compiler to start...")
|
201
189
|
if not compile_server.wait_for_startup():
|
202
190
|
print("Failed to start local compiler.")
|
@@ -209,47 +197,11 @@ def _try_start_server_or_get_url(args: argparse.Namespace) -> str | CompileServe
|
|
209
197
|
return DEFAULT_URL
|
210
198
|
|
211
199
|
|
212
|
-
def _lots_and_lots_of_files(directory: Path) -> bool:
|
213
|
-
count = 0
|
214
|
-
for root, dirs, files in os.walk(directory):
|
215
|
-
count += len(files)
|
216
|
-
if count > 100:
|
217
|
-
return True
|
218
|
-
return False
|
219
|
-
|
220
|
-
|
221
|
-
def _looks_like_sketch_directory(directory: Path) -> bool:
|
222
|
-
if looks_like_fastled_repo(directory):
|
223
|
-
print("Directory looks like the FastLED repo")
|
224
|
-
return False
|
225
|
-
|
226
|
-
if _lots_and_lots_of_files(directory):
|
227
|
-
print("Too many files in the directory, bailing out")
|
228
|
-
return False
|
229
|
-
|
230
|
-
# walk the path and if there are over 30 files, return False
|
231
|
-
# at the root of the directory there should either be an ino file or a src directory
|
232
|
-
# or some cpp files
|
233
|
-
# if there is a platformio.ini file, return True
|
234
|
-
ino_file_at_root = list(directory.glob("*.ino"))
|
235
|
-
if ino_file_at_root:
|
236
|
-
return True
|
237
|
-
cpp_file_at_root = list(directory.glob("*.cpp"))
|
238
|
-
if cpp_file_at_root:
|
239
|
-
return True
|
240
|
-
platformini_file = list(directory.glob("platformio.ini"))
|
241
|
-
if platformini_file:
|
242
|
-
return True
|
243
|
-
return False
|
244
|
-
|
245
|
-
|
246
200
|
def run_client(args: argparse.Namespace) -> int:
|
247
201
|
compile_server: CompileServer | None = None
|
248
202
|
open_web_browser = not args.just_compile
|
249
203
|
profile = args.profile
|
250
|
-
if not args.force_compile and not
|
251
|
-
Path(args.directory)
|
252
|
-
):
|
204
|
+
if not args.force_compile and not looks_like_sketch_directory(Path(args.directory)):
|
253
205
|
print(
|
254
206
|
"Error: Not a valid FastLED sketch directory, if you are sure it is, use --force-compile"
|
255
207
|
)
|
@@ -370,11 +322,9 @@ def run_client(args: argparse.Namespace) -> int:
|
|
370
322
|
|
371
323
|
def run_server(args: argparse.Namespace) -> int:
|
372
324
|
interactive = args.interactive
|
373
|
-
compile_server = CompileServer(
|
374
|
-
|
375
|
-
|
376
|
-
print(f"Server started at {compile_server.url()}")
|
377
|
-
compile_server.start()
|
325
|
+
compile_server = CompileServer(interactive=interactive)
|
326
|
+
if not interactive:
|
327
|
+
print(f"Server started at {compile_server.url()}")
|
378
328
|
compile_server.wait_for_startup()
|
379
329
|
try:
|
380
330
|
while True:
|
@@ -408,9 +358,13 @@ def main() -> int:
|
|
408
358
|
|
409
359
|
if __name__ == "__main__":
|
410
360
|
try:
|
361
|
+
project_root = Path(__file__).resolve().parent.parent.parent
|
362
|
+
print(f"Project root: {project_root}")
|
363
|
+
os.chdir(project_root)
|
364
|
+
os.chdir("../fastled")
|
411
365
|
sys.argv.append("examples/wasm")
|
412
|
-
sys.argv.append("
|
413
|
-
sys.argv.append("
|
366
|
+
sys.argv.append("--server")
|
367
|
+
sys.argv.append("--interactive")
|
414
368
|
sys.exit(main())
|
415
369
|
except KeyboardInterrupt:
|
416
370
|
print("\nExiting from main...")
|
fastled/compile_server.py
CHANGED
@@ -8,6 +8,7 @@ from typing import Optional
|
|
8
8
|
import httpx
|
9
9
|
|
10
10
|
from fastled.docker_manager import DockerManager
|
11
|
+
from fastled.sketch import looks_like_fastled_repo
|
11
12
|
|
12
13
|
_DEFAULT_CONTAINER_NAME = "fastled-wasm-compiler"
|
13
14
|
|
@@ -27,19 +28,10 @@ def find_available_port(start_port: int = SERVER_PORT) -> int:
|
|
27
28
|
raise RuntimeError("No available ports found")
|
28
29
|
|
29
30
|
|
30
|
-
def looks_like_fastled_repo(directory: Path) -> bool:
|
31
|
-
libprops = directory / "library.properties"
|
32
|
-
if not libprops.exists():
|
33
|
-
return False
|
34
|
-
txt = libprops.read_text()
|
35
|
-
return "FastLED" in txt
|
36
|
-
|
37
|
-
|
38
31
|
class CompileServer:
|
39
32
|
def __init__(
|
40
33
|
self,
|
41
34
|
container_name=_DEFAULT_CONTAINER_NAME,
|
42
|
-
disable_auto_clean: bool = False,
|
43
35
|
interactive: bool = False,
|
44
36
|
) -> None:
|
45
37
|
|
@@ -52,14 +44,13 @@ class CompileServer:
|
|
52
44
|
fastled_src_dir = cwd / "src"
|
53
45
|
|
54
46
|
self.container_name = container_name
|
55
|
-
self.disable_auto_clean = disable_auto_clean
|
56
47
|
self.docker = DockerManager(container_name=container_name)
|
57
48
|
self.running = False
|
58
49
|
self.thread: Optional[threading.Thread] = None
|
59
50
|
self.running_process: subprocess.Popen | None = None
|
60
51
|
self.fastled_src_dir: Path | None = fastled_src_dir
|
61
52
|
self.interactive = interactive
|
62
|
-
self._port = self.
|
53
|
+
self._port = self._start()
|
63
54
|
|
64
55
|
def port(self) -> int:
|
65
56
|
return self._port
|
@@ -91,7 +82,7 @@ class CompileServer:
|
|
91
82
|
return False
|
92
83
|
return False
|
93
84
|
|
94
|
-
def
|
85
|
+
def _start(self) -> int:
|
95
86
|
print("Compiling server starting")
|
96
87
|
self.running = True
|
97
88
|
# Ensure Docker is running
|
@@ -141,24 +132,20 @@ class CompileServer:
|
|
141
132
|
server_command = ["/bin/bash"]
|
142
133
|
else:
|
143
134
|
server_command = ["python", "/js/run.py", "server"]
|
144
|
-
if self.disable_auto_clean:
|
145
|
-
server_command.append("--disable-auto-clean")
|
146
135
|
print(f"Started Docker container with command: {server_command}")
|
147
136
|
ports = {port: 80}
|
148
137
|
volumes = None
|
149
138
|
if self.fastled_src_dir:
|
150
139
|
print(
|
151
|
-
f"Mounting FastLED source directory {self.fastled_src_dir} into container /
|
140
|
+
f"Mounting FastLED source directory {self.fastled_src_dir} into container /host/fastled/src"
|
152
141
|
)
|
153
142
|
volumes = {
|
154
|
-
str(self.fastled_src_dir): {"bind": "/
|
143
|
+
str(self.fastled_src_dir): {"bind": "/host/fastled/src", "mode": "ro"}
|
155
144
|
}
|
156
|
-
# no auto-update because the source directory is mapped in.
|
157
|
-
server_command.append("--no-auto-update") # stop git repo updates.
|
158
145
|
if not self.interactive:
|
159
|
-
|
160
|
-
|
161
|
-
) #
|
146
|
+
# no auto-update because the source directory is mapped in.
|
147
|
+
# This should be automatic now.
|
148
|
+
server_command.append("--no-auto-update") # stop git repo updates.
|
162
149
|
self.running_process = self.docker.run_container(
|
163
150
|
server_command, ports=ports, volumes=volumes
|
164
151
|
)
|
fastled/sketch.py
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
import os
|
2
|
+
from pathlib import Path
|
3
|
+
|
4
|
+
|
5
|
+
def get_sketch_files(directory: Path) -> list[Path]:
|
6
|
+
files: list[Path] = []
|
7
|
+
for root, dirs, filenames in os.walk(directory):
|
8
|
+
# ignore hidden directories
|
9
|
+
dirs[:] = [d for d in dirs if not d.startswith(".")]
|
10
|
+
# ignore fastled_js directory
|
11
|
+
dirs[:] = [d for d in dirs if "fastled_js" not in d]
|
12
|
+
# ignore hidden files
|
13
|
+
filenames = [f for f in filenames if not f.startswith(".")]
|
14
|
+
for filename in filenames:
|
15
|
+
if "platformio.ini" in filename:
|
16
|
+
continue
|
17
|
+
files.append(Path(root) / filename)
|
18
|
+
return files
|
19
|
+
|
20
|
+
|
21
|
+
def looks_like_fastled_repo(directory: Path) -> bool:
|
22
|
+
libprops = directory / "library.properties"
|
23
|
+
if not libprops.exists():
|
24
|
+
return False
|
25
|
+
txt = libprops.read_text(encoding="utf-8", errors="ignore")
|
26
|
+
return "FastLED" in txt
|
27
|
+
|
28
|
+
|
29
|
+
def _lots_and_lots_of_files(directory: Path) -> bool:
|
30
|
+
return len(get_sketch_files(directory)) > 100
|
31
|
+
|
32
|
+
|
33
|
+
def looks_like_sketch_directory(directory: Path) -> bool:
|
34
|
+
if looks_like_fastled_repo(directory):
|
35
|
+
print("Directory looks like the FastLED repo")
|
36
|
+
return False
|
37
|
+
|
38
|
+
if _lots_and_lots_of_files(directory):
|
39
|
+
print("Too many files in the directory, bailing out")
|
40
|
+
return False
|
41
|
+
|
42
|
+
# walk the path and if there are over 30 files, return False
|
43
|
+
# at the root of the directory there should either be an ino file or a src directory
|
44
|
+
# or some cpp files
|
45
|
+
# if there is a platformio.ini file, return True
|
46
|
+
ino_file_at_root = list(directory.glob("*.ino"))
|
47
|
+
if ino_file_at_root:
|
48
|
+
return True
|
49
|
+
cpp_file_at_root = list(directory.glob("*.cpp"))
|
50
|
+
if cpp_file_at_root:
|
51
|
+
return True
|
52
|
+
platformini_file = list(directory.glob("platformio.ini"))
|
53
|
+
if platformini_file:
|
54
|
+
return True
|
55
|
+
return False
|
fastled/web_compile.py
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
+
import io
|
1
2
|
import shutil
|
2
3
|
import tempfile
|
4
|
+
import zipfile
|
3
5
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
4
6
|
from dataclasses import dataclass
|
5
7
|
from pathlib import Path
|
@@ -8,12 +10,15 @@ import httpx
|
|
8
10
|
|
9
11
|
from fastled.build_mode import BuildMode
|
10
12
|
from fastled.compile_server import SERVER_PORT
|
13
|
+
from fastled.sketch import get_sketch_files
|
11
14
|
|
12
15
|
DEFAULT_HOST = "https://fastled.onrender.com"
|
13
16
|
ENDPOINT_COMPILED_WASM = "compile/wasm"
|
14
17
|
_TIMEOUT = 60 * 4 # 2 mins timeout
|
15
18
|
_AUTH_TOKEN = "oBOT5jbsO4ztgrpNsQwlmFLIKB"
|
16
19
|
|
20
|
+
_THREAD_POOL = ThreadPoolExecutor(max_workers=8)
|
21
|
+
|
17
22
|
|
18
23
|
@dataclass
|
19
24
|
class TestConnectionResult:
|
@@ -58,7 +63,7 @@ def _test_connection(host: str, use_ipv4: bool) -> TestConnectionResult:
|
|
58
63
|
transport=transport,
|
59
64
|
) as test_client:
|
60
65
|
test_response = test_client.get(
|
61
|
-
f"{host}/healthz", timeout=
|
66
|
+
f"{host}/healthz", timeout=3, follow_redirects=True
|
62
67
|
)
|
63
68
|
result = TestConnectionResult(
|
64
69
|
host, test_response.status_code == 200, use_ipv4
|
@@ -70,6 +75,27 @@ def _test_connection(host: str, use_ipv4: bool) -> TestConnectionResult:
|
|
70
75
|
return result
|
71
76
|
|
72
77
|
|
78
|
+
def zip_files(directory: Path) -> bytes | Exception:
|
79
|
+
print("Zipping files...")
|
80
|
+
try:
|
81
|
+
files = get_sketch_files(directory)
|
82
|
+
if not files:
|
83
|
+
raise FileNotFoundError(f"No files found in {directory}")
|
84
|
+
for f in files:
|
85
|
+
print(f"Adding file: {f}")
|
86
|
+
# Create in-memory zip file
|
87
|
+
zip_buffer = io.BytesIO()
|
88
|
+
with zipfile.ZipFile(
|
89
|
+
zip_buffer, "w", zipfile.ZIP_DEFLATED, compresslevel=9
|
90
|
+
) as zip_file:
|
91
|
+
for file_path in files:
|
92
|
+
relative_path = file_path.relative_to(directory)
|
93
|
+
zip_file.write(file_path, str(Path("wasm") / relative_path))
|
94
|
+
return zip_buffer.getvalue()
|
95
|
+
except Exception as e:
|
96
|
+
return e
|
97
|
+
|
98
|
+
|
73
99
|
def web_compile(
|
74
100
|
directory: Path,
|
75
101
|
host: str | None = None,
|
@@ -80,131 +106,117 @@ def web_compile(
|
|
80
106
|
host = _sanitize_host(host or DEFAULT_HOST)
|
81
107
|
print("Compiling on", host)
|
82
108
|
auth_token = auth_token or _AUTH_TOKEN
|
83
|
-
# zip up the files
|
84
|
-
print("Zipping files...")
|
85
109
|
|
86
|
-
|
87
|
-
|
88
|
-
# Create temporary directory for organizing files
|
89
|
-
with tempfile.TemporaryDirectory() as temp_dir:
|
90
|
-
# Create wasm subdirectory
|
91
|
-
wasm_dir = Path(temp_dir) / "wasm"
|
92
|
-
|
93
|
-
# Copy all files from source to wasm subdirectory, excluding fastled_js
|
94
|
-
def ignore_fastled_js(dir: str, files: list[str]) -> list[str]:
|
95
|
-
if "fastled_js" in dir:
|
96
|
-
return files
|
97
|
-
if dir.startswith("."):
|
98
|
-
return files
|
99
|
-
return []
|
100
|
-
|
101
|
-
shutil.copytree(directory, wasm_dir, ignore=ignore_fastled_js)
|
102
|
-
# Create zip archive from the temp directory
|
103
|
-
shutil.make_archive(tmp_zip.name[:-4], "zip", temp_dir)
|
110
|
+
if not directory.exists():
|
111
|
+
raise FileNotFoundError(f"Directory not found: {directory}")
|
104
112
|
|
113
|
+
zip_bytes = zip_files(directory)
|
114
|
+
if isinstance(zip_bytes, Exception):
|
115
|
+
return WebCompileResult(
|
116
|
+
success=False, stdout=str(zip_bytes), hash_value=None, zip_bytes=b""
|
117
|
+
)
|
118
|
+
archive_size = len(zip_bytes)
|
105
119
|
print(f"Web compiling on {host}...")
|
106
|
-
|
107
120
|
try:
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
zip_bytes=b"",
|
144
|
-
)
|
145
|
-
assert test_connection_result is not None
|
146
|
-
ipv4_stmt = "IPv4" if test_connection_result.ipv4 else "IPv6"
|
147
|
-
transport = (
|
148
|
-
httpx.HTTPTransport(local_address="0.0.0.0")
|
149
|
-
if test_connection_result.ipv4
|
150
|
-
else None
|
121
|
+
|
122
|
+
files = {"file": ("wasm.zip", zip_bytes, "application/x-zip-compressed")}
|
123
|
+
urls = [host]
|
124
|
+
domain = host.split("://")[-1]
|
125
|
+
if ":" not in domain:
|
126
|
+
urls.append(f"{host}:{SERVER_PORT}")
|
127
|
+
test_connection_result: TestConnectionResult | None = None
|
128
|
+
|
129
|
+
futures: list = []
|
130
|
+
ip_versions = [True, False] if "localhost" not in host else [True]
|
131
|
+
for ipv4 in ip_versions:
|
132
|
+
for url in urls:
|
133
|
+
f = _THREAD_POOL.submit(_test_connection, url, ipv4)
|
134
|
+
futures.append(f)
|
135
|
+
|
136
|
+
succeeded = False
|
137
|
+
for future in as_completed(futures):
|
138
|
+
result: TestConnectionResult = future.result()
|
139
|
+
|
140
|
+
if result.success:
|
141
|
+
print(f"Connection successful to {result.host}")
|
142
|
+
succeeded = True
|
143
|
+
# host = test_url
|
144
|
+
test_connection_result = result
|
145
|
+
break
|
146
|
+
else:
|
147
|
+
print(f"Ignoring {result.host} due to connection failure")
|
148
|
+
|
149
|
+
if not succeeded:
|
150
|
+
print("Connection failed to all endpoints")
|
151
|
+
return WebCompileResult(
|
152
|
+
success=False,
|
153
|
+
stdout="Connection failed",
|
154
|
+
hash_value=None,
|
155
|
+
zip_bytes=b"",
|
151
156
|
)
|
152
|
-
|
153
|
-
|
157
|
+
assert test_connection_result is not None
|
158
|
+
ipv4_stmt = "IPv4" if test_connection_result.ipv4 else "IPv6"
|
159
|
+
transport = (
|
160
|
+
httpx.HTTPTransport(local_address="0.0.0.0")
|
161
|
+
if test_connection_result.ipv4
|
162
|
+
else None
|
163
|
+
)
|
164
|
+
with httpx.Client(
|
165
|
+
transport=transport,
|
166
|
+
timeout=_TIMEOUT,
|
167
|
+
) as client:
|
168
|
+
headers = {
|
169
|
+
"accept": "application/json",
|
170
|
+
"authorization": auth_token,
|
171
|
+
"build": (
|
172
|
+
build_mode.value.lower()
|
173
|
+
if build_mode
|
174
|
+
else BuildMode.QUICK.value.lower()
|
175
|
+
),
|
176
|
+
"profile": "true" if profile else "false",
|
177
|
+
}
|
178
|
+
|
179
|
+
url = f"{test_connection_result.host}/{ENDPOINT_COMPILED_WASM}"
|
180
|
+
print(f"Compiling on {url} via {ipv4_stmt}. Zip size: {archive_size} bytes")
|
181
|
+
response = client.post(
|
182
|
+
url,
|
183
|
+
follow_redirects=True,
|
184
|
+
files=files,
|
185
|
+
headers=headers,
|
154
186
|
timeout=_TIMEOUT,
|
155
|
-
)
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
else BuildMode.QUICK.value.lower()
|
163
|
-
),
|
164
|
-
"profile": "true" if profile else "false",
|
165
|
-
}
|
166
|
-
|
167
|
-
url = f"{test_connection_result.host}/{ENDPOINT_COMPILED_WASM}"
|
168
|
-
print(f"Compiling on {url} via {ipv4_stmt}")
|
169
|
-
response = client.post(
|
170
|
-
url,
|
171
|
-
follow_redirects=True,
|
172
|
-
files=files,
|
173
|
-
headers=headers,
|
174
|
-
timeout=_TIMEOUT,
|
187
|
+
)
|
188
|
+
|
189
|
+
if response.status_code != 200:
|
190
|
+
json_response = response.json()
|
191
|
+
detail = json_response.get("detail", "Could not compile")
|
192
|
+
return WebCompileResult(
|
193
|
+
success=False, stdout=detail, hash_value=None, zip_bytes=b""
|
175
194
|
)
|
176
195
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
return WebCompileResult(
|
203
|
-
success=True,
|
204
|
-
stdout=stdout,
|
205
|
-
hash_value=hash_value,
|
206
|
-
zip_bytes=response.content,
|
207
|
-
)
|
196
|
+
print(f"Response status code: {response}")
|
197
|
+
# Create a temporary directory to extract the zip
|
198
|
+
with tempfile.TemporaryDirectory() as extract_dir:
|
199
|
+
extract_path = Path(extract_dir)
|
200
|
+
|
201
|
+
# Write the response content to a temporary zip file
|
202
|
+
temp_zip = extract_path / "response.zip"
|
203
|
+
temp_zip.write_bytes(response.content)
|
204
|
+
|
205
|
+
# Extract the zip
|
206
|
+
shutil.unpack_archive(temp_zip, extract_path, "zip")
|
207
|
+
|
208
|
+
# Read stdout from out.txt if it exists
|
209
|
+
stdout_file = extract_path / "out.txt"
|
210
|
+
hash_file = extract_path / "hash.txt"
|
211
|
+
stdout = stdout_file.read_text() if stdout_file.exists() else ""
|
212
|
+
hash_value = hash_file.read_text() if hash_file.exists() else None
|
213
|
+
|
214
|
+
return WebCompileResult(
|
215
|
+
success=True,
|
216
|
+
stdout=stdout,
|
217
|
+
hash_value=hash_value,
|
218
|
+
zip_bytes=response.content,
|
219
|
+
)
|
208
220
|
except KeyboardInterrupt:
|
209
221
|
print("Keyboard interrupt")
|
210
222
|
raise
|
@@ -213,8 +225,3 @@ def web_compile(
|
|
213
225
|
return WebCompileResult(
|
214
226
|
success=False, stdout=str(e), hash_value=None, zip_bytes=b""
|
215
227
|
)
|
216
|
-
finally:
|
217
|
-
try:
|
218
|
-
Path(tmp_zip.name).unlink()
|
219
|
-
except PermissionError:
|
220
|
-
print("Warning: Could not delete temporary zip file")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: fastled
|
3
|
-
Version: 1.1.
|
3
|
+
Version: 1.1.7
|
4
4
|
Summary: FastLED Wasm Compiler
|
5
5
|
Home-page: https://github.com/zackees/fastled-wasm
|
6
6
|
Maintainer: Zachary Vorhies
|
@@ -89,8 +89,13 @@ Pre-processing is done to your source files. A fake Arduino.h will be inserted i
|
|
89
89
|
provide shims for most of the common api points.
|
90
90
|
|
91
91
|
|
92
|
+
|
92
93
|
# Revisions
|
93
94
|
|
95
|
+
* 1.1.7 - Sketch cache re-enabled, but selectively invalidated on cpp/h updates. Cleaned up deprecated args. Fixed double thread running for containers that was causing slowdown.
|
96
|
+
* 1.1.6 - Use the fast src volume map allow quick updates to fastled when developing on the source code.
|
97
|
+
* 1.1.5 - Filter out hidden files and directories from being included in the sketch archive sent to the compiler.
|
98
|
+
* 1.1.4 - Fix regression introduced by testing out ipv4/ipv6 connections from a thread pool.
|
94
99
|
* 1.1.3 - Live editing of *.h and *.cpp files is now possible. Sketch cache will be disabled in this mode.
|
95
100
|
* 1.1.2 - `--server` will now volume map fastled src directory if it detects this. This was also implemented on the docker side.
|
96
101
|
* 1.1.1 - `--interactive` is now supported to debug the container. Volume maps and better compatibilty with ipv4/v6 by concurrent connection finding.
|
@@ -1,18 +1,19 @@
|
|
1
1
|
fastled/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
fastled/app.py,sha256=
|
2
|
+
fastled/app.py,sha256=UT8FD9GtXhSlSl9NGWnqa3Ncx-BP__2ItihingGAlHE,12350
|
3
3
|
fastled/build_mode.py,sha256=joMwsV4K1y_LijT4gEAcjx69RZBoe_KmFmHZdPYbL_4,631
|
4
4
|
fastled/check_cpp_syntax.py,sha256=YxRJm7cFPv4bdhL1v_KOkBz8RL86ihayoJYvclr69ms,1024
|
5
5
|
fastled/cli.py,sha256=CNR_pQR0sNVPNuv8e_nmm-0PI8sU-eUBUgnWgWkzW9c,237
|
6
|
-
fastled/compile_server.py,sha256=
|
6
|
+
fastled/compile_server.py,sha256=8avG0mAjdjU0w1ej4LiKVGLgkHi8dZxT48TLuGecj7A,9451
|
7
7
|
fastled/docker_manager.py,sha256=WcOKa3EpIPAjICPfTL87CUYuAmX9KYT6L_Hcqbj95eE,9028
|
8
8
|
fastled/filewatcher.py,sha256=SHKx9Dnt4EJiT-iPYakdPZBRIL1gsJGN9tY8FJW2myU,5079
|
9
9
|
fastled/open_browser.py,sha256=-VhpGmydwLCcXmrDD2esMEdJPZYcoX2Mt73eb88Nna0,1392
|
10
10
|
fastled/paths.py,sha256=VsPmgu0lNSCFOoEC0BsTYzDygXqy15AHUfN-tTuzDZA,99
|
11
|
-
fastled/
|
11
|
+
fastled/sketch.py,sha256=KhhPFqlFVlBk8YrzFy7-ioe7zEzecgrVLhyFbLpBp7k,1845
|
12
|
+
fastled/web_compile.py,sha256=vVQ68lldGo3CaQcYGf3lh9yU6K_A3zP1gNJ29pi5J-E,7857
|
12
13
|
fastled/assets/example.txt,sha256=lTBovRjiz0_TgtAtbA1C5hNi2ffbqnNPqkKg6UiKCT8,54
|
13
|
-
fastled-1.1.
|
14
|
-
fastled-1.1.
|
15
|
-
fastled-1.1.
|
16
|
-
fastled-1.1.
|
17
|
-
fastled-1.1.
|
18
|
-
fastled-1.1.
|
14
|
+
fastled-1.1.7.dist-info/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
|
15
|
+
fastled-1.1.7.dist-info/METADATA,sha256=Ow53B9iSxPA-Pm91xqPMu7muCptTNqup3N4UR4qTDCg,6192
|
16
|
+
fastled-1.1.7.dist-info/WHEEL,sha256=0VNUDWQJzfRahYI3neAhz2UVbRCtztpN5dPHAGvmGXc,109
|
17
|
+
fastled-1.1.7.dist-info/entry_points.txt,sha256=RCwmzCSOS4-C2i9EziANq7Z2Zb4KFnEMR1FQC0bBwAw,101
|
18
|
+
fastled-1.1.7.dist-info/top_level.txt,sha256=xfG6Z_ol9V5YmBROkZq2QTRwjbS2ouCUxaTJsOwfkOo,14
|
19
|
+
fastled-1.1.7.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|