fastled 1.1.7__py2.py3-none-any.whl → 1.1.15__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/__init__.py CHANGED
@@ -0,0 +1,3 @@
1
+ """FastLED Wasm Compiler package."""
2
+
3
+ __version__ = "1.1.15"
fastled/app.py CHANGED
@@ -1,7 +1,5 @@
1
1
  """
2
2
  Uses the latest wasm compiler image to compile the FastLED sketch.
3
-
4
-
5
3
  """
6
4
 
7
5
  import argparse
@@ -15,13 +13,20 @@ import time
15
13
  from dataclasses import dataclass
16
14
  from pathlib import Path
17
15
 
16
+ from fastled import __version__
18
17
  from fastled.build_mode import BuildMode, get_build_mode
19
- from fastled.compile_server import CompileServer, looks_like_fastled_repo
18
+ from fastled.compile_server import CompileServer
20
19
  from fastled.docker_manager import DockerManager
21
- from fastled.filewatcher import FileChangedNotifier
20
+ from fastled.filewatcher import FileWatcherProcess
21
+ from fastled.keyboard import SpaceBarWatcher
22
22
  from fastled.open_browser import open_browser_thread
23
- from fastled.sketch import looks_like_sketch_directory
24
- from fastled.web_compile import web_compile
23
+ from fastled.sketch import looks_like_fastled_repo, looks_like_sketch_directory
24
+ from fastled.web_compile import (
25
+ SERVER_PORT,
26
+ ConnectionResult,
27
+ find_good_connection,
28
+ web_compile,
29
+ )
25
30
 
26
31
  machine = platform.machine().lower()
27
32
  IS_ARM: bool = "arm" in machine or "aarch64" in machine
@@ -44,7 +49,10 @@ DOCKER = DockerManager(container_name=CONTAINER_NAME)
44
49
 
45
50
  def parse_args() -> argparse.Namespace:
46
51
  """Parse command-line arguments."""
47
- parser = argparse.ArgumentParser(description="FastLED WASM Compiler")
52
+ parser = argparse.ArgumentParser(description=f"FastLED WASM Compiler {__version__}")
53
+ parser.add_argument(
54
+ "--version", action="version", version=f"%(prog)s {__version__}"
55
+ )
48
56
  parser.add_argument(
49
57
  "directory",
50
58
  type=str,
@@ -88,6 +96,12 @@ def parse_args() -> argparse.Namespace:
88
96
  build_mode.add_argument(
89
97
  "--release", action="store_true", help="Build in release mode"
90
98
  )
99
+ build_mode.add_argument(
100
+ "--localhost",
101
+ "--local",
102
+ action="store_true",
103
+ help="Use localhost for web compilation from an instance of fastled --server, creating it if necessary",
104
+ )
91
105
  build_mode.add_argument(
92
106
  "--server",
93
107
  action="store_true",
@@ -100,9 +114,20 @@ def parse_args() -> argparse.Namespace:
100
114
  help="Skips the test to see if the current directory is a valid FastLED sketch directory",
101
115
  )
102
116
 
117
+ cwd_is_fastled = looks_like_fastled_repo(Path(os.getcwd()))
118
+
103
119
  args = parser.parse_args()
104
- if args.server and args.web:
105
- parser.error("--server and --web are mutually exclusive")
120
+ if not cwd_is_fastled and not args.localhost and not args.web and not args.server:
121
+ print(f"Using web compiler at {DEFAULT_URL}")
122
+ args.web = DEFAULT_URL
123
+ if cwd_is_fastled and not args.web:
124
+ print("Forcing --local mode because we are in the FastLED repo")
125
+ args.localhost = True
126
+ if args.localhost:
127
+ args.web = "localhost"
128
+ if args.interactive and not args.server:
129
+ print("--interactive forces --server mode")
130
+ args.server = True
106
131
  if args.directory is None and not args.server:
107
132
  # does current directory look like a sketch?
108
133
  maybe_sketch_dir = Path(os.getcwd())
@@ -113,6 +138,7 @@ def parse_args() -> argparse.Namespace:
113
138
  "\nYou either need to specify a sketch directory or run in --server mode."
114
139
  )
115
140
  sys.exit(1)
141
+
116
142
  return args
117
143
 
118
144
 
@@ -176,7 +202,24 @@ def run_web_compiler(
176
202
 
177
203
 
178
204
  def _try_start_server_or_get_url(args: argparse.Namespace) -> str | CompileServer:
179
- if args.web:
205
+ is_local_host = "localhost" in args.web or "127.0.0.1" in args.web or args.localhost
206
+
207
+ # test to see if there is already a local host server
208
+ local_host_needs_server = False
209
+ if is_local_host:
210
+ addr = "localhost" if args.localhost else args.web
211
+ urls = [addr]
212
+ if ":" not in addr:
213
+ urls.append(f"{addr}:{SERVER_PORT}")
214
+
215
+ result: ConnectionResult | None = find_good_connection(urls)
216
+ if result is not None:
217
+ print(f"Found local server at {result.host}")
218
+ return result.host
219
+ else:
220
+ local_host_needs_server = True
221
+
222
+ if not local_host_needs_server and args.web:
180
223
  if isinstance(args.web, str):
181
224
  return args.web
182
225
  if isinstance(args.web, bool):
@@ -184,6 +227,7 @@ def _try_start_server_or_get_url(args: argparse.Namespace) -> str | CompileServe
184
227
  return args.web
185
228
  else:
186
229
  try:
230
+ print("No local server found, starting one...")
187
231
  compile_server = CompileServer()
188
232
  print("Waiting for the local compiler to start...")
189
233
  if not compile_server.wait_for_startup():
@@ -199,7 +243,7 @@ def _try_start_server_or_get_url(args: argparse.Namespace) -> str | CompileServe
199
243
 
200
244
  def run_client(args: argparse.Namespace) -> int:
201
245
  compile_server: CompileServer | None = None
202
- open_web_browser = not args.just_compile
246
+ open_web_browser = not args.just_compile and not args.interactive
203
247
  profile = args.profile
204
248
  if not args.force_compile and not looks_like_sketch_directory(Path(args.directory)):
205
249
  print(
@@ -280,40 +324,76 @@ def run_client(args: argparse.Namespace) -> int:
280
324
  compile_server.stop()
281
325
  return 1
282
326
 
283
- # Watch mode
284
327
  print("\nWatching for changes. Press Ctrl+C to stop...")
285
- watcher = FileChangedNotifier(args.directory, excluded_patterns=["fastled_js"])
286
- watcher.start()
328
+ sketch_filewatcher = FileWatcherProcess(
329
+ args.directory, excluded_patterns=["fastled_js"]
330
+ )
331
+
332
+ source_code_watcher: FileWatcherProcess | None = None
333
+ if compile_server and compile_server.using_fastled_src_dir_volume():
334
+ assert compile_server.fastled_src_dir is not None
335
+ source_code_watcher = FileWatcherProcess(
336
+ compile_server.fastled_src_dir, excluded_patterns=[]
337
+ )
338
+
339
+ def trigger_rebuild_if_sketch_changed(
340
+ last_compiled_result: CompiledResult,
341
+ ) -> CompiledResult:
342
+ changed_files = sketch_filewatcher.get_all_changes()
343
+ if changed_files:
344
+ print(f"\nChanges detected in {changed_files}")
345
+ last_hash_value = last_compiled_result.hash_value
346
+ out = compile_function(last_hash_value=last_hash_value)
347
+ if not out.success:
348
+ print("\nRecompilation failed.")
349
+ else:
350
+ print("\nRecompilation successful.")
351
+ return out
352
+ return last_compiled_result
287
353
 
288
354
  try:
289
355
  while True:
290
- try:
291
- changed_files = watcher.get_all_changes()
292
- except KeyboardInterrupt:
293
- print("\nExiting from watcher...")
294
- raise
295
- except Exception as e:
296
- print(f"Error getting changes: {e}")
297
- changed_files = []
298
- if changed_files:
299
- print(f"\nChanges detected in {changed_files}")
300
- last_hash_value = last_compiled_result.hash_value
301
- result = compile_function(last_hash_value=last_hash_value)
302
- if not result.success:
303
- print("\nRecompilation failed.")
304
- else:
305
- print("\nRecompilation successful.")
306
- time.sleep(0.3)
356
+ last_compiled_result = trigger_rebuild_if_sketch_changed(
357
+ last_compiled_result
358
+ )
359
+ if compile_server and not compile_server.proceess_running():
360
+ print("Server process is not running. Exiting...")
361
+ return 1
362
+ if source_code_watcher is not None:
363
+ changed_files = source_code_watcher.get_all_changes()
364
+ # de-duplicate changes
365
+ changed_files = sorted(list(set(changed_files)))
366
+ if changed_files:
367
+ print(f"\nChanges detected in FastLED source code: {changed_files}")
368
+ print("Press space bar to trigger compile.")
369
+
370
+ space_key_watcher = SpaceBarWatcher()
371
+ try:
372
+ while True:
373
+ if space_key_watcher.space_bar_pressed():
374
+ print("Space bar pressed, triggering recompile...")
375
+ last_compiled_result = compile_function(
376
+ last_hash_value=None
377
+ )
378
+ print("Finished recompile.")
379
+ break
380
+ elif len(sketch_filewatcher.get_all_changes()) > 0:
381
+ last_compiled_result = compile_function(
382
+ last_hash_value=None
383
+ )
384
+ break
385
+ time.sleep(0.1)
386
+ finally:
387
+ space_key_watcher.stop()
388
+
307
389
  except KeyboardInterrupt:
308
- watcher.stop()
309
390
  print("\nStopping watch mode...")
310
391
  return 0
311
392
  except Exception as e:
312
- watcher.stop()
313
393
  print(f"Error: {e}")
314
394
  return 1
315
395
  finally:
316
- watcher.stop()
396
+ sketch_filewatcher.stop()
317
397
  if compile_server:
318
398
  compile_server.stop()
319
399
  if browser_proc:
@@ -342,13 +422,7 @@ def run_server(args: argparse.Namespace) -> int:
342
422
 
343
423
  def main() -> int:
344
424
  args = parse_args()
345
- target_dir = Path(args.directory)
346
- cwd_is_target_dir = target_dir == Path(os.getcwd())
347
- force_server = cwd_is_target_dir and looks_like_fastled_repo(target_dir)
348
- auto_server = (args.server or args.interactive or cwd_is_target_dir) and (
349
- not args.web and not args.just_compile
350
- )
351
- if auto_server or force_server:
425
+ if args.server:
352
426
  print("Running in server only mode.")
353
427
  return run_server(args)
354
428
  else:
@@ -358,13 +432,9 @@ def main() -> int:
358
432
 
359
433
  if __name__ == "__main__":
360
434
  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")
365
- sys.argv.append("examples/wasm")
366
- sys.argv.append("--server")
367
- sys.argv.append("--interactive")
435
+ # os.chdir("../fastled")
436
+ sys.argv.append("examples/SdCard")
437
+ sys.argv.append("--localhost")
368
438
  sys.exit(main())
369
439
  except KeyboardInterrupt:
370
440
  print("\nExiting from main...")