fastled 1.2.83__tar.gz → 1.2.86__tar.gz

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.
Files changed (133) hide show
  1. {fastled-1.2.83 → fastled-1.2.86}/.gitignore +1 -0
  2. {fastled-1.2.83 → fastled-1.2.86}/PKG-INFO +1 -1
  3. fastled-1.2.86/build_local_docker.py +47 -0
  4. {fastled-1.2.83 → fastled-1.2.86}/compiler/server.py +62 -41
  5. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/__init__.py +1 -1
  6. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/client_server.py +8 -2
  7. fastled-1.2.86/src/fastled/server_flask.py +473 -0
  8. {fastled-1.2.83 → fastled-1.2.86}/src/fastled.egg-info/PKG-INFO +1 -1
  9. {fastled-1.2.83 → fastled-1.2.86}/src/fastled.egg-info/SOURCES.txt +1 -0
  10. {fastled-1.2.83 → fastled-1.2.86}/test +4 -0
  11. {fastled-1.2.83 → fastled-1.2.86}/tests/unit/test_fetch_source_files.py +12 -1
  12. fastled-1.2.83/src/fastled/server_flask.py +0 -267
  13. {fastled-1.2.83 → fastled-1.2.86}/.aiderignore +0 -0
  14. {fastled-1.2.83 → fastled-1.2.86}/.dockerignore +0 -0
  15. {fastled-1.2.83 → fastled-1.2.86}/.github/workflows/build_multi_docker_image.yml +0 -0
  16. {fastled-1.2.83 → fastled-1.2.86}/.github/workflows/build_webpage.yml +0 -0
  17. {fastled-1.2.83 → fastled-1.2.86}/.github/workflows/lint.yml +0 -0
  18. {fastled-1.2.83 → fastled-1.2.86}/.github/workflows/publish_release.yml +0 -0
  19. {fastled-1.2.83 → fastled-1.2.86}/.github/workflows/template_build_docker_image.yml +0 -0
  20. {fastled-1.2.83 → fastled-1.2.86}/.github/workflows/test_build_exe.yml +0 -0
  21. {fastled-1.2.83 → fastled-1.2.86}/.github/workflows/test_macos.yml +0 -0
  22. {fastled-1.2.83 → fastled-1.2.86}/.github/workflows/test_ubuntu.yml +0 -0
  23. {fastled-1.2.83 → fastled-1.2.86}/.github/workflows/test_win.yml +0 -0
  24. {fastled-1.2.83 → fastled-1.2.86}/.pylintrc +0 -0
  25. {fastled-1.2.83 → fastled-1.2.86}/.vscode/launch.json +0 -0
  26. {fastled-1.2.83 → fastled-1.2.86}/.vscode/settings.json +0 -0
  27. {fastled-1.2.83 → fastled-1.2.86}/.vscode/tasks.json +0 -0
  28. {fastled-1.2.83 → fastled-1.2.86}/Dockerfile +0 -0
  29. {fastled-1.2.83 → fastled-1.2.86}/LICENSE +0 -0
  30. {fastled-1.2.83 → fastled-1.2.86}/MANIFEST.in +0 -0
  31. {fastled-1.2.83 → fastled-1.2.86}/README.md +0 -0
  32. {fastled-1.2.83 → fastled-1.2.86}/RELEASE.md +0 -0
  33. {fastled-1.2.83 → fastled-1.2.86}/TODO.md +0 -0
  34. {fastled-1.2.83 → fastled-1.2.86}/build_exe.py +0 -0
  35. {fastled-1.2.83 → fastled-1.2.86}/build_site.py +0 -0
  36. {fastled-1.2.83 → fastled-1.2.86}/clean +0 -0
  37. {fastled-1.2.83 → fastled-1.2.86}/compiler/CMakeLists.txt +0 -0
  38. {fastled-1.2.83 → fastled-1.2.86}/compiler/__init__.py +0 -0
  39. {fastled-1.2.83 → fastled-1.2.86}/compiler/arduino-pre-process.sh +0 -0
  40. {fastled-1.2.83 → fastled-1.2.86}/compiler/build.sh +0 -0
  41. {fastled-1.2.83 → fastled-1.2.86}/compiler/build_archive.sh +0 -0
  42. {fastled-1.2.83 → fastled-1.2.86}/compiler/build_fast.sh +0 -0
  43. {fastled-1.2.83 → fastled-1.2.86}/compiler/code_sync.py +0 -0
  44. {fastled-1.2.83 → fastled-1.2.86}/compiler/compile.py +0 -0
  45. {fastled-1.2.83 → fastled-1.2.86}/compiler/compile_lock.py +0 -0
  46. {fastled-1.2.83 → fastled-1.2.86}/compiler/debug.sh +0 -0
  47. {fastled-1.2.83 → fastled-1.2.86}/compiler/entrypoint.sh +0 -0
  48. {fastled-1.2.83 → fastled-1.2.86}/compiler/extra/100dots.html +0 -0
  49. {fastled-1.2.83 → fastled-1.2.86}/compiler/extra/demo_threejs.html +0 -0
  50. {fastled-1.2.83 → fastled-1.2.86}/compiler/extra/micdemo.html +0 -0
  51. {fastled-1.2.83 → fastled-1.2.86}/compiler/extra/mp3upload.html +0 -0
  52. {fastled-1.2.83 → fastled-1.2.86}/compiler/extra/webgl_postprocessing_unreal_bloom.html +0 -0
  53. {fastled-1.2.83 → fastled-1.2.86}/compiler/final_prewarm.sh +0 -0
  54. {fastled-1.2.83 → fastled-1.2.86}/compiler/init_runtime.py +0 -0
  55. {fastled-1.2.83 → fastled-1.2.86}/compiler/install-arduino-cli.sh +0 -0
  56. {fastled-1.2.83 → fastled-1.2.86}/compiler/libcompile/CMakeLists.txt +0 -0
  57. {fastled-1.2.83 → fastled-1.2.86}/compiler/paths.py +0 -0
  58. {fastled-1.2.83 → fastled-1.2.86}/compiler/pre-process.sh +0 -0
  59. {fastled-1.2.83 → fastled-1.2.86}/compiler/prewarm.sh +0 -0
  60. {fastled-1.2.83 → fastled-1.2.86}/compiler/process-ino.py +0 -0
  61. {fastled-1.2.83 → fastled-1.2.86}/compiler/process_extended.py +0 -0
  62. {fastled-1.2.83 → fastled-1.2.86}/compiler/pyproject.toml +0 -0
  63. {fastled-1.2.83 → fastled-1.2.86}/compiler/run.py +0 -0
  64. {fastled-1.2.83 → fastled-1.2.86}/compiler/sketch_hasher.py +0 -0
  65. {fastled-1.2.83 → fastled-1.2.86}/compiler/wasm_compiler_flags.py +0 -0
  66. {fastled-1.2.83 → fastled-1.2.86}/docker-compose.yml +0 -0
  67. {fastled-1.2.83 → fastled-1.2.86}/install +0 -0
  68. {fastled-1.2.83 → fastled-1.2.86}/install_linux.sh +0 -0
  69. {fastled-1.2.83 → fastled-1.2.86}/lint +0 -0
  70. {fastled-1.2.83 → fastled-1.2.86}/pyproject.toml +0 -0
  71. {fastled-1.2.83 → fastled-1.2.86}/requirements.testing.txt +0 -0
  72. {fastled-1.2.83 → fastled-1.2.86}/setup.cfg +0 -0
  73. {fastled-1.2.83 → fastled-1.2.86}/setup.py +0 -0
  74. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/app.py +0 -0
  75. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/assets/example.txt +0 -0
  76. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/assets/localhost-key.pem +0 -0
  77. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/assets/localhost.pem +0 -0
  78. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/cli.py +0 -0
  79. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/cli_test.py +0 -0
  80. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/cli_test_interactive.py +0 -0
  81. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/compile_server.py +0 -0
  82. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/compile_server_impl.py +0 -0
  83. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/docker_manager.py +0 -0
  84. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/filewatcher.py +0 -0
  85. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/keyboard.py +0 -0
  86. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/keyz.py +0 -0
  87. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/live_client.py +0 -0
  88. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/open_browser.py +0 -0
  89. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/parse_args.py +0 -0
  90. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/paths.py +0 -0
  91. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/print_filter.py +0 -0
  92. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/project_init.py +0 -0
  93. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/select_sketch_directory.py +0 -0
  94. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/server_start.py +0 -0
  95. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/settings.py +0 -0
  96. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/site/build.py +0 -0
  97. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/site/examples.py +0 -0
  98. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/sketch.py +0 -0
  99. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/spinner.py +0 -0
  100. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/string_diff.py +0 -0
  101. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/test/can_run_local_docker_tests.py +0 -0
  102. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/test/examples.py +0 -0
  103. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/types.py +0 -0
  104. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/util.py +0 -0
  105. {fastled-1.2.83 → fastled-1.2.86}/src/fastled/web_compile.py +0 -0
  106. {fastled-1.2.83 → fastled-1.2.86}/src/fastled.egg-info/dependency_links.txt +0 -0
  107. {fastled-1.2.83 → fastled-1.2.86}/src/fastled.egg-info/entry_points.txt +0 -0
  108. {fastled-1.2.83 → fastled-1.2.86}/src/fastled.egg-info/requires.txt +0 -0
  109. {fastled-1.2.83 → fastled-1.2.86}/src/fastled.egg-info/top_level.txt +0 -0
  110. {fastled-1.2.83 → fastled-1.2.86}/tests/integration/test_build_examples.py +0 -0
  111. {fastled-1.2.83 → fastled-1.2.86}/tests/integration/test_examples.py +0 -0
  112. {fastled-1.2.83 → fastled-1.2.86}/tests/unit/html/index.html +0 -0
  113. {fastled-1.2.83 → fastled-1.2.86}/tests/unit/test_api.py +0 -0
  114. {fastled-1.2.83 → fastled-1.2.86}/tests/unit/test_bad_ino.py +0 -0
  115. {fastled-1.2.83 → fastled-1.2.86}/tests/unit/test_cli.py +0 -0
  116. {fastled-1.2.83 → fastled-1.2.86}/tests/unit/test_compile_server.py +0 -0
  117. {fastled-1.2.83 → fastled-1.2.86}/tests/unit/test_docker_linux_on_windows.py +0 -0
  118. {fastled-1.2.83 → fastled-1.2.86}/tests/unit/test_embedded_data.py +0 -0
  119. {fastled-1.2.83 → fastled-1.2.86}/tests/unit/test_filechanger.py +0 -0
  120. {fastled-1.2.83 → fastled-1.2.86}/tests/unit/test_http_server.py +0 -0
  121. {fastled-1.2.83 → fastled-1.2.86}/tests/unit/test_ino/bad/bad.ino +0 -0
  122. {fastled-1.2.83 → fastled-1.2.86}/tests/unit/test_ino/bad_platformio/bad_platformio.ino +0 -0
  123. {fastled-1.2.83 → fastled-1.2.86}/tests/unit/test_ino/bad_platformio/platformio.ini +0 -0
  124. {fastled-1.2.83 → fastled-1.2.86}/tests/unit/test_ino/embedded/data/bigdata.dat +0 -0
  125. {fastled-1.2.83 → fastled-1.2.86}/tests/unit/test_ino/embedded/wasm.ino +0 -0
  126. {fastled-1.2.83 → fastled-1.2.86}/tests/unit/test_ino/wasm/wasm.ino +0 -0
  127. {fastled-1.2.83 → fastled-1.2.86}/tests/unit/test_print_filter.py +0 -0
  128. {fastled-1.2.83 → fastled-1.2.86}/tests/unit/test_project_init.py +0 -0
  129. {fastled-1.2.83 → fastled-1.2.86}/tests/unit/test_server_and_client_seperatly.py +0 -0
  130. {fastled-1.2.83 → fastled-1.2.86}/tests/unit/test_string_diff.py +0 -0
  131. {fastled-1.2.83 → fastled-1.2.86}/tests/unit/test_version.py +0 -0
  132. {fastled-1.2.83 → fastled-1.2.86}/tests/unit/test_webcompile.py +0 -0
  133. {fastled-1.2.83 → fastled-1.2.86}/upload_package.sh +0 -0
@@ -150,3 +150,4 @@ tmp/
150
150
  cache/
151
151
  dist/
152
152
  /fastled/
153
+ logs
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastled
3
- Version: 1.2.83
3
+ Version: 1.2.86
4
4
  Summary: FastLED Wasm Compiler
5
5
  Home-page: https://github.com/zackees/fastled-wasm
6
6
  Maintainer: Zachary Vorhies
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env -S uv run
2
+
3
+ # Requirements:
4
+ # - python-dateutil
5
+
6
+ # pyproject.toml
7
+ # [project]
8
+ # dependencies = [
9
+ # "python-dateutil"
10
+ # ]
11
+
12
+ import os
13
+ import shutil
14
+ import subprocess
15
+
16
+ def _exec(cmd: str) -> int:
17
+ print(f"$ {cmd}")
18
+ return subprocess.call(cmd, shell=True)
19
+
20
+ # Step 1: Stop containers and remove images
21
+ _exec("docker compose down --remove-orphans --rmi all")
22
+
23
+ # Step 2: Remove all dangling images
24
+ _exec("docker image prune -f")
25
+
26
+ # Step 3: Remove all images matching niteris/fastled-wasm
27
+ images = subprocess.check_output(
28
+ "docker images --format '{{.Repository}} {{.ID}}'",
29
+ shell=True, text=True
30
+ )
31
+
32
+ for line in images.strip().splitlines():
33
+ repo, image_id = line.split()
34
+ if repo == "niteris/fastled-wasm":
35
+ _exec(f"docker rmi {image_id}")
36
+
37
+ # Step 4: Optionally remove volumes
38
+ # _exec("docker volume prune -f") # Uncomment if you want to purge volumes too
39
+
40
+ # Step 5: Remove local build artifacts (e.g., PlatformIO)
41
+ if os.path.exists("build"):
42
+ print("Removing local build/ directory")
43
+ shutil.rmtree("build")
44
+
45
+
46
+ # Step 6: Rebuild images
47
+ _exec("docker compose build")
@@ -431,6 +431,34 @@ def get_settings() -> dict:
431
431
  return settings
432
432
 
433
433
 
434
+ # Return content and media type
435
+ def fetch_file(full_path: Path) -> tuple[bytes, str] | HTTPException:
436
+ """Fetch the file from the server."""
437
+ print(f"Fetching file: {full_path}")
438
+ if not full_path.exists():
439
+ raise HTTPException(status_code=404, detail="File not found.")
440
+ if not full_path.is_file():
441
+ raise HTTPException(status_code=400, detail="Not a file.")
442
+ if not full_path.is_relative_to(FASTLED_SRC) and not full_path.is_relative_to(
443
+ "/emsdk"
444
+ ):
445
+ raise HTTPException(status_code=400, detail="Invalid file path.")
446
+
447
+ content = full_path.read_bytes()
448
+ # Determine media type based on file extension
449
+ media_type = "text/plain"
450
+ if full_path.suffix in [".h", ".cpp"]:
451
+ media_type = "text/plain"
452
+ elif full_path.suffix == ".html":
453
+ media_type = "text/html"
454
+ elif full_path.suffix == ".js":
455
+ media_type = "application/javascript"
456
+ elif full_path.suffix == ".css":
457
+ media_type = "text/css"
458
+
459
+ return content, media_type
460
+
461
+
434
462
  def startup() -> None:
435
463
  print("Starting FastLED wasm compiler server...")
436
464
  try:
@@ -599,37 +627,22 @@ def project_init_example(
599
627
 
600
628
 
601
629
  @app.get("/sourcefiles/{filepath:path}")
602
- def source_file(filepath: str) -> FileResponse:
630
+ def source_file(filepath: str) -> Response:
603
631
  """Get the source file from the server."""
604
632
  print(f"Endpoint accessed: /sourcefiles/{filepath}")
605
633
  if ".." in filepath:
606
634
  raise HTTPException(status_code=400, detail="Invalid file path.")
607
635
  full_path = Path(FASTLED_SRC / filepath)
608
- if not full_path.exists():
609
- raise HTTPException(status_code=404, detail="File not found.")
610
- if not full_path.is_file():
611
- raise HTTPException(status_code=400, detail="Not a file.")
612
- if not full_path.is_relative_to(FASTLED_SRC):
613
- raise HTTPException(status_code=400, detail="Invalid file path.")
614
-
615
- suffix = full_path.suffix
616
- if suffix in [".h", ".cpp"]:
617
- media_type = "text/plain"
618
- elif suffix == ".html":
619
- media_type = "text/html"
620
- elif suffix == ".js":
621
- media_type = "application/javascript"
622
- elif suffix == ".css":
623
- media_type = "text/css"
624
- else:
625
- media_type = "application/octet-stream"
626
-
627
- fr = FileResponse(
628
- path=full_path,
629
- media_type=media_type,
630
- filename=filepath,
631
- )
632
- return fr
636
+ result: tuple[bytes, str] | HTTPException = fetch_file(full_path=full_path)
637
+ if isinstance(result, HTTPException):
638
+ assert isinstance(result, HTTPException)
639
+ return Response(
640
+ content=result.detail, # type: ignore
641
+ media_type="text/plain",
642
+ status_code=result.status_code, # type: ignore
643
+ )
644
+ content, media_type = result
645
+ return Response(content=content, media_type=media_type)
633
646
 
634
647
 
635
648
  @app.get("/drawfsource/{file_path:path}")
@@ -642,21 +655,29 @@ async def static_files(file_path: str) -> Response:
642
655
  # Extract the path after "js/fastled/src/"
643
656
  relative_path = file_path[len("js/fastled/src/") :]
644
657
  full_path = FASTLED_SRC / relative_path
645
-
646
- if full_path.exists() and full_path.is_file():
647
- content = full_path.read_bytes()
648
- # Determine media type based on file extension
649
- media_type = "text/plain"
650
- if full_path.suffix in [".h", ".cpp"]:
651
- media_type = "text/plain"
652
- elif full_path.suffix == ".html":
653
- media_type = "text/html"
654
- elif full_path.suffix == ".js":
655
- media_type = "application/javascript"
656
- elif full_path.suffix == ".css":
657
- media_type = "text/css"
658
-
659
- return Response(content=content, media_type=media_type)
658
+ result: tuple[bytes, str] | HTTPException = fetch_file(full_path=full_path)
659
+
660
+ # return Response(content=content, media_type=media_type)
661
+ if isinstance(result, HTTPException):
662
+ return Response(
663
+ content=result.detail, # type: ignore
664
+ media_type="text/plain",
665
+ status_code=result.status_code, # type: ignore
666
+ )
667
+ content, media_type = result
668
+ return Response(content=content, media_type=media_type)
669
+ elif file_path.startswith("js/drawfsource/emsdk/"):
670
+ relative_path = file_path[len("js/drawfsource/emsdk/") :]
671
+ full_path = Path("/") / "emsdk" / relative_path
672
+ result: tuple[bytes, str] | HTTPException = fetch_file(full_path=full_path)
673
+ if isinstance(result, HTTPException):
674
+ return Response(
675
+ content=result.detail, # type: ignore
676
+ media_type="text/plain",
677
+ status_code=result.status_code, # type: ignore
678
+ )
679
+ content, media_type = result
680
+ return Response(content=content, media_type=media_type)
660
681
 
661
682
  # If file not found or path doesn't match expected format
662
683
  return Response(
@@ -14,7 +14,7 @@ from .types import BuildMode, CompileResult, CompileServerError, FileResponse
14
14
  # IMPORTANT! There's a bug in github which will REJECT any version update
15
15
  # that has any other change in the repo. Please bump the version as the
16
16
  # ONLY change in a commit, or else the pypi update and the release will fail.
17
- __version__ = "1.2.83"
17
+ __version__ = "1.2.86"
18
18
 
19
19
 
20
20
  class Api:
@@ -63,6 +63,12 @@ def TEST_BEFORE_COMPILE(url) -> None:
63
63
  pass
64
64
 
65
65
 
66
+ def _chunked_print(stdout: str) -> None:
67
+ lines = stdout.splitlines()
68
+ for line in lines:
69
+ print(line)
70
+
71
+
66
72
  def _run_web_compiler(
67
73
  directory: Path,
68
74
  host: str,
@@ -80,7 +86,7 @@ def _run_web_compiler(
80
86
  if not web_result.success:
81
87
  print("\nWeb compilation failed:")
82
88
  print(f"Time taken: {diff:.2f} seconds")
83
- print(web_result.stdout)
89
+ _chunked_print(web_result.stdout)
84
90
  # Create error page
85
91
  output_dir.mkdir(exist_ok=True)
86
92
  error_html = _create_error_html(web_result.stdout)
@@ -117,7 +123,7 @@ def _run_web_compiler(
117
123
  # Extract zip contents
118
124
  shutil.unpack_archive(temp_zip, output_dir, "zip")
119
125
 
120
- print(web_result.stdout)
126
+ _chunked_print(web_result.stdout)
121
127
  print_results()
122
128
  return web_result
123
129