fastled 1.0.12__py2.py3-none-any.whl → 1.0.17__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/sketch.py DELETED
@@ -1,55 +0,0 @@
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/util.py DELETED
@@ -1,10 +0,0 @@
1
- import hashlib
2
- from pathlib import Path
3
-
4
-
5
- def hash_file(file_path: Path) -> str:
6
- hasher = hashlib.sha256()
7
- with open(file_path, "rb") as f:
8
- for chunk in iter(lambda: f.read(4096), b""):
9
- hasher.update(chunk)
10
- return hasher.hexdigest()
fastled/web_compile.py DELETED
@@ -1,284 +0,0 @@
1
- import io
2
- import json
3
- import os
4
- import shutil
5
- import tempfile
6
- import zipfile
7
- from concurrent.futures import Future, ProcessPoolExecutor, as_completed
8
- from dataclasses import dataclass
9
- from pathlib import Path
10
-
11
- import httpx
12
-
13
- from fastled.build_mode import BuildMode
14
- from fastled.compile_server import SERVER_PORT
15
- from fastled.sketch import get_sketch_files
16
- from fastled.util import hash_file
17
-
18
- DEFAULT_HOST = "https://fastled.onrender.com"
19
- ENDPOINT_COMPILED_WASM = "compile/wasm"
20
- _TIMEOUT = 60 * 4 # 2 mins timeout
21
- _AUTH_TOKEN = "oBOT5jbsO4ztgrpNsQwlmFLIKB"
22
- ENABLE_EMBEDDED_DATA = True
23
- _EXECUTOR = ProcessPoolExecutor(max_workers=8)
24
-
25
-
26
- @dataclass
27
- class ConnectionResult:
28
- host: str
29
- success: bool
30
- ipv4: bool
31
-
32
-
33
- @dataclass
34
- class WebCompileResult:
35
- success: bool
36
- stdout: str
37
- hash_value: str | None
38
- zip_bytes: bytes
39
-
40
- def __bool__(self) -> bool:
41
- return self.success
42
-
43
-
44
- def _sanitize_host(host: str) -> str:
45
- if host.startswith("http"):
46
- return host
47
- is_local_host = "localhost" in host or "127.0.0.1" in host or "0.0.0.0" in host
48
- use_https = not is_local_host
49
- if use_https:
50
- return host if host.startswith("https://") else f"https://{host}"
51
- return host if host.startswith("http://") else f"http://{host}"
52
-
53
-
54
- def _test_connection(host: str, use_ipv4: bool) -> ConnectionResult:
55
- # Function static cache
56
- connection_cache = _test_connection.__dict__.setdefault("_CONNECTION_CACHE", {})
57
- key = f"{host}_{use_ipv4}"
58
- cached_result = connection_cache.get(key)
59
- if cached_result is not None:
60
- return cached_result
61
- transport = httpx.HTTPTransport(local_address="0.0.0.0") if use_ipv4 else None
62
- try:
63
- with httpx.Client(
64
- timeout=_TIMEOUT,
65
- transport=transport,
66
- ) as test_client:
67
- test_response = test_client.get(
68
- f"{host}/healthz", timeout=3, follow_redirects=True
69
- )
70
- result = ConnectionResult(host, test_response.status_code == 200, use_ipv4)
71
- except Exception:
72
- result = ConnectionResult(host, False, use_ipv4)
73
- connection_cache[key] = result
74
- return result
75
-
76
-
77
- def _file_info(file_path: Path) -> str:
78
- hash_txt = hash_file(file_path)
79
- file_size = file_path.stat().st_size
80
- json_str = json.dumps({"hash": hash_txt, "size": file_size})
81
- return json_str
82
-
83
-
84
- @dataclass
85
- class ZipResult:
86
- zip_bytes: bytes
87
- zip_embedded_bytes: bytes | None
88
- success: bool
89
- error: str | None
90
-
91
-
92
- def zip_files(directory: Path) -> ZipResult | Exception:
93
- print("Zipping files...")
94
- try:
95
- files = get_sketch_files(directory)
96
- if not files:
97
- raise FileNotFoundError(f"No files found in {directory}")
98
- for f in files:
99
- print(f"Adding file: {f}")
100
- # Create in-memory zip file
101
- has_embedded_zip = False
102
- zip_embedded_buffer = io.BytesIO()
103
- zip_buffer = io.BytesIO()
104
- with zipfile.ZipFile(
105
- zip_embedded_buffer, "w", zipfile.ZIP_DEFLATED, compresslevel=9
106
- ) as emebedded_zip_file:
107
- with zipfile.ZipFile(
108
- zip_buffer, "w", zipfile.ZIP_DEFLATED, compresslevel=9
109
- ) as zip_file:
110
- for file_path in files:
111
- relative_path = file_path.relative_to(directory)
112
- achive_path = str(Path("wasm") / relative_path)
113
- if str(relative_path).startswith("data") and ENABLE_EMBEDDED_DATA:
114
- _file_info_str = _file_info(file_path)
115
- zip_file.writestr(
116
- achive_path + ".embedded.json", _file_info_str
117
- )
118
- emebedded_zip_file.write(file_path, relative_path)
119
- has_embedded_zip = True
120
- else:
121
- zip_file.write(file_path, achive_path)
122
- result = ZipResult(
123
- zip_bytes=zip_buffer.getvalue(),
124
- zip_embedded_bytes=(
125
- zip_embedded_buffer.getvalue() if has_embedded_zip else None
126
- ),
127
- success=True,
128
- error=None,
129
- )
130
- return result
131
- except Exception as e:
132
- return e
133
-
134
-
135
- def find_good_connection(
136
- urls: list[str], filter_out_bad=False
137
- ) -> ConnectionResult | None:
138
- futures: list[Future] = []
139
- ip_versions = [True, False]
140
- # Start all connection tests
141
- for ipv4 in ip_versions:
142
- for url in urls:
143
- f = _EXECUTOR.submit(_test_connection, url, ipv4)
144
- futures.append(f)
145
-
146
- try:
147
- # Return first successful result
148
- for future in as_completed(futures):
149
- result: ConnectionResult = future.result()
150
- if result.success or not filter_out_bad:
151
- return result
152
- finally:
153
- # Cancel any remaining futures
154
- for future in futures:
155
- future.cancel()
156
- return None
157
-
158
-
159
- def web_compile(
160
- directory: Path,
161
- host: str | None = None,
162
- auth_token: str | None = None,
163
- build_mode: BuildMode | None = None,
164
- profile: bool = False,
165
- ) -> WebCompileResult:
166
- host = _sanitize_host(host or DEFAULT_HOST)
167
- print("Compiling on", host)
168
- auth_token = auth_token or _AUTH_TOKEN
169
- if not directory.exists():
170
- raise FileNotFoundError(f"Directory not found: {directory}")
171
- zip_result = zip_files(directory)
172
- if isinstance(zip_result, Exception):
173
- return WebCompileResult(
174
- success=False, stdout=str(zip_result), hash_value=None, zip_bytes=b""
175
- )
176
- zip_bytes = zip_result.zip_bytes
177
- archive_size = len(zip_bytes)
178
- print(f"Web compiling on {host}...")
179
- try:
180
- urls = [host]
181
- domain = host.split("://")[-1]
182
- if ":" not in domain:
183
- urls.append(f"{host}:{SERVER_PORT}")
184
-
185
- connection_result = find_good_connection(urls)
186
- if connection_result is None:
187
- print("Connection failed to all endpoints")
188
- return WebCompileResult(
189
- success=False,
190
- stdout="Connection failed",
191
- hash_value=None,
192
- zip_bytes=b"",
193
- )
194
-
195
- ipv4_stmt = "IPv4" if connection_result.ipv4 else "IPv6"
196
- transport = (
197
- httpx.HTTPTransport(local_address="0.0.0.0")
198
- if connection_result.ipv4
199
- else None
200
- )
201
- with httpx.Client(
202
- transport=transport,
203
- timeout=_TIMEOUT,
204
- ) as client:
205
- headers = {
206
- "accept": "application/json",
207
- "authorization": auth_token,
208
- "build": (
209
- build_mode.value.lower()
210
- if build_mode
211
- else BuildMode.QUICK.value.lower()
212
- ),
213
- "profile": "true" if profile else "false",
214
- }
215
-
216
- url = f"{connection_result.host}/{ENDPOINT_COMPILED_WASM}"
217
- print(f"Compiling on {url} via {ipv4_stmt}. Zip size: {archive_size} bytes")
218
- files = {"file": ("wasm.zip", zip_bytes, "application/x-zip-compressed")}
219
- response = client.post(
220
- url,
221
- follow_redirects=True,
222
- files=files,
223
- headers=headers,
224
- timeout=_TIMEOUT,
225
- )
226
-
227
- if response.status_code != 200:
228
- json_response = response.json()
229
- detail = json_response.get("detail", "Could not compile")
230
- return WebCompileResult(
231
- success=False, stdout=detail, hash_value=None, zip_bytes=b""
232
- )
233
-
234
- print(f"Response status code: {response}")
235
- # Create a temporary directory to extract the zip
236
- with tempfile.TemporaryDirectory() as extract_dir:
237
- extract_path = Path(extract_dir)
238
-
239
- # Write the response content to a temporary zip file
240
- temp_zip = extract_path / "response.zip"
241
- temp_zip.write_bytes(response.content)
242
-
243
- # Extract the zip
244
- shutil.unpack_archive(temp_zip, extract_path, "zip")
245
-
246
- if zip_result.zip_embedded_bytes:
247
- # extract the embedded bytes, which were not sent to the server
248
- temp_zip.write_bytes(zip_result.zip_embedded_bytes)
249
- shutil.unpack_archive(temp_zip, extract_path, "zip")
250
-
251
- # we don't need the temp zip anymore
252
- temp_zip.unlink()
253
-
254
- # Read stdout from out.txt if it exists
255
- stdout_file = extract_path / "out.txt"
256
- hash_file = extract_path / "hash.txt"
257
- stdout = stdout_file.read_text() if stdout_file.exists() else ""
258
- hash_value = hash_file.read_text() if hash_file.exists() else None
259
-
260
- # now rezip the extracted files since we added the embedded json files
261
- out_buffer = io.BytesIO()
262
- with zipfile.ZipFile(
263
- out_buffer, "w", zipfile.ZIP_DEFLATED, compresslevel=9
264
- ) as out_zip:
265
- for root, _, _files in os.walk(extract_path):
266
- for file in _files:
267
- file_path = Path(root) / file
268
- relative_path = file_path.relative_to(extract_path)
269
- out_zip.write(file_path, relative_path)
270
-
271
- return WebCompileResult(
272
- success=True,
273
- stdout=stdout,
274
- hash_value=hash_value,
275
- zip_bytes=out_buffer.getvalue(),
276
- )
277
- except KeyboardInterrupt:
278
- print("Keyboard interrupt")
279
- raise
280
- except httpx.HTTPError as e:
281
- print(f"Error: {e}")
282
- return WebCompileResult(
283
- success=False, stdout=str(e), hash_value=None, zip_bytes=b""
284
- )
@@ -1,20 +0,0 @@
1
- fastled/__init__.py,sha256=XO4EYoMURe1bnLz9dzABggQ31idNxZwqUDWnM5CR1oY,64
2
- fastled/app.py,sha256=VB_uJDrFDvPgJuPh8crntWztKteWmHp5porqNSCCXu4,14949
3
- fastled/build_mode.py,sha256=joMwsV4K1y_LijT4gEAcjx69RZBoe_KmFmHZdPYbL_4,631
4
- fastled/cli.py,sha256=CNR_pQR0sNVPNuv8e_nmm-0PI8sU-eUBUgnWgWkzW9c,237
5
- fastled/compile_server.py,sha256=Om9fFpg9Yx4_WJDC_pG5-tYtAwreKrEAx-k8dJQBkJs,8146
6
- fastled/docker_manager.py,sha256=gaDZpFV7E-9JhYIn6ahkP--9dGT32-WR5wZaU-o--6g,9107
7
- fastled/filewatcher.py,sha256=fJNMQRDCpihSL4nQeYPqbD4m1Jzjcz_-YRAo-wlPW6k,6518
8
- fastled/keyboard.py,sha256=PiAUhga8R_crMqFQRwjKyg6bgVTMlpezWa0gaGmL_So,2542
9
- fastled/open_browser.py,sha256=RRHcsZ5Vzsw1AuZUEYuSfjKmf_9j3NGMDUR-FndHmqs,1483
10
- fastled/paths.py,sha256=VsPmgu0lNSCFOoEC0BsTYzDygXqy15AHUfN-tTuzDZA,99
11
- fastled/sketch.py,sha256=KhhPFqlFVlBk8YrzFy7-ioe7zEzecgrVLhyFbLpBp7k,1845
12
- fastled/util.py,sha256=t4M3NFMhnCzfYbLvIyJi0RdFssZqbTN_vVIaej1WV-U,265
13
- fastled/web_compile.py,sha256=RqHGiG9ZV3siQVhnQ8Ff7p-5aUKCwQWdoxs-zk7ItDE,10149
14
- fastled/assets/example.txt,sha256=lTBovRjiz0_TgtAtbA1C5hNi2ffbqnNPqkKg6UiKCT8,54
15
- fastled-1.0.12.dist-info/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
16
- fastled-1.0.12.dist-info/METADATA,sha256=fpErTM2GXagl_3JPvnrw8b3SUIJ6jeTPa-QFkTilAfc,6919
17
- fastled-1.0.12.dist-info/WHEEL,sha256=0VNUDWQJzfRahYI3neAhz2UVbRCtztpN5dPHAGvmGXc,109
18
- fastled-1.0.12.dist-info/entry_points.txt,sha256=RCwmzCSOS4-C2i9EziANq7Z2Zb4KFnEMR1FQC0bBwAw,101
19
- fastled-1.0.12.dist-info/top_level.txt,sha256=xfG6Z_ol9V5YmBROkZq2QTRwjbS2ouCUxaTJsOwfkOo,14
20
- fastled-1.0.12.dist-info/RECORD,,
@@ -1,4 +0,0 @@
1
- [console_scripts]
2
- fastled = fastled.cli:main
3
- fastled-wasm = fastled.cli:main
4
- fled = fastled.cli:main
@@ -1,2 +0,0 @@
1
- cache
2
- fastled
File without changes
File without changes
File without changes