fastled 1.3.36__py3-none-any.whl → 1.3.38__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/__main__.py +14 -0
- fastled/__version__.py +1 -1
- fastled/client_server.py +15 -1
- fastled/string_diff.py +76 -26
- fastled/web_compile.py +10 -2
- {fastled-1.3.36.dist-info → fastled-1.3.38.dist-info}/METADATA +1 -1
- {fastled-1.3.36.dist-info → fastled-1.3.38.dist-info}/RECORD +11 -10
- {fastled-1.3.36.dist-info → fastled-1.3.38.dist-info}/WHEEL +0 -0
- {fastled-1.3.36.dist-info → fastled-1.3.38.dist-info}/entry_points.txt +0 -0
- {fastled-1.3.36.dist-info → fastled-1.3.38.dist-info}/licenses/LICENSE +0 -0
- {fastled-1.3.36.dist-info → fastled-1.3.38.dist-info}/top_level.txt +0 -0
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
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# IMPORTANT! There's a bug in github which will REJECT any version update
|
2
2
|
# that has any other change in the repo. Please bump the version as the
|
3
3
|
# ONLY change in a commit, or else the pypi update and the release will fail.
|
4
|
-
__version__ = "1.3.
|
4
|
+
__version__ = "1.3.38"
|
5
5
|
|
6
6
|
__version_url_latest__ = "https://raw.githubusercontent.com/zackees/fastled-wasm/refs/heads/main/src/fastled/__version__.py"
|
fastled/client_server.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import shutil
|
2
|
+
import sys
|
2
3
|
import tempfile
|
3
4
|
import threading
|
4
5
|
import time
|
@@ -67,7 +68,20 @@ def TEST_BEFORE_COMPILE(url) -> None:
|
|
67
68
|
def _chunked_print(stdout: str) -> None:
|
68
69
|
lines = stdout.splitlines()
|
69
70
|
for line in lines:
|
70
|
-
|
71
|
+
try:
|
72
|
+
print(line)
|
73
|
+
except UnicodeEncodeError:
|
74
|
+
# On Windows, the console may not support Unicode characters
|
75
|
+
# Try to encode the line with the console's encoding and replace problematic characters
|
76
|
+
try:
|
77
|
+
console_encoding = sys.stdout.encoding or "utf-8"
|
78
|
+
encoded_line = line.encode(console_encoding, errors="replace").decode(
|
79
|
+
console_encoding
|
80
|
+
)
|
81
|
+
print(encoded_line)
|
82
|
+
except Exception:
|
83
|
+
# If all else fails, just print the line without problematic characters
|
84
|
+
print(line.encode("ascii", errors="replace").decode("ascii"))
|
71
85
|
|
72
86
|
|
73
87
|
def _run_web_compiler(
|
fastled/string_diff.py
CHANGED
@@ -10,11 +10,14 @@ def _filter_out_obvious_bad_choices(
|
|
10
10
|
Filter out strings that are too different from the input string.
|
11
11
|
This is a heuristic and may not be perfect.
|
12
12
|
"""
|
13
|
-
|
13
|
+
if not input_str.strip(): # Handle empty input
|
14
|
+
return string_list
|
15
|
+
|
16
|
+
input_chars = set(input_str.lower())
|
14
17
|
filtered_list = []
|
15
18
|
for s in string_list:
|
16
19
|
# Check if at least half of the input characters are in the string
|
17
|
-
s_chars = set(s)
|
20
|
+
s_chars = set(s.lower())
|
18
21
|
common_chars = input_chars.intersection(s_chars)
|
19
22
|
if len(common_chars) >= len(input_chars) / 2:
|
20
23
|
filtered_list.append(s)
|
@@ -29,8 +32,8 @@ def is_in_order_match(input_str: str, other: str) -> bool:
|
|
29
32
|
"""
|
30
33
|
|
31
34
|
# Remove spaces from input string for matching
|
32
|
-
input_chars = [c for c in input_str if c != " "]
|
33
|
-
other_chars =
|
35
|
+
input_chars = [c.lower() for c in input_str if c != " "]
|
36
|
+
other_chars = [c.lower() for c in other]
|
34
37
|
input_index = 0
|
35
38
|
other_index = 0
|
36
39
|
while input_index < len(input_chars) and other_index < len(other_chars):
|
@@ -53,6 +56,14 @@ def string_diff(
|
|
53
56
|
def normalize(s: str) -> str:
|
54
57
|
return s.lower() if ignore_case else s
|
55
58
|
|
59
|
+
# Handle empty input or empty list
|
60
|
+
if not input_string.strip():
|
61
|
+
# Return all strings with equal distance for empty input
|
62
|
+
return [(i, s) for i, s in enumerate(string_list)]
|
63
|
+
|
64
|
+
if not string_list:
|
65
|
+
return []
|
66
|
+
|
56
67
|
map_string: dict[str, str] = {}
|
57
68
|
|
58
69
|
if ignore_case:
|
@@ -60,38 +71,71 @@ def string_diff(
|
|
60
71
|
else:
|
61
72
|
map_string = {s: s for s in string_list}
|
62
73
|
|
74
|
+
original_string_list = string_list.copy()
|
63
75
|
if ignore_case:
|
64
76
|
string_list = [s.lower() for s in string_list]
|
65
77
|
input_string = input_string.lower()
|
66
78
|
|
79
|
+
# Check for exact matches, but also check if there are other substring matches
|
80
|
+
exact_matches = [s for s in string_list if s == input_string]
|
81
|
+
substring_matches = [s for s in string_list if input_string in s]
|
82
|
+
|
83
|
+
# If there's an exact match AND other substring matches, return all substring matches
|
84
|
+
# This provides better user experience for partial matching
|
85
|
+
if exact_matches and len(substring_matches) > 1:
|
86
|
+
out: list[tuple[float, str]] = []
|
87
|
+
for i, s in enumerate(substring_matches):
|
88
|
+
s_mapped = map_string.get(s, s)
|
89
|
+
out.append((i, s_mapped))
|
90
|
+
return out
|
91
|
+
|
92
|
+
# If there's only an exact match and no other substring matches, return just the exact match
|
93
|
+
if exact_matches and len(substring_matches) == 1:
|
94
|
+
out: list[tuple[float, str]] = []
|
95
|
+
for i, s in enumerate(exact_matches):
|
96
|
+
s_mapped = map_string.get(s, s)
|
97
|
+
out.append((i, s_mapped))
|
98
|
+
return out
|
99
|
+
|
67
100
|
# Apply set membership filtering for queries with 3+ characters
|
68
|
-
if len(input_string) >= 3:
|
69
|
-
|
101
|
+
if len(input_string.strip()) >= 3:
|
102
|
+
filtered = _filter_out_obvious_bad_choices(input_string, string_list)
|
103
|
+
if filtered: # Only apply filter if it doesn't eliminate everything
|
104
|
+
string_list = filtered
|
70
105
|
|
71
106
|
# Second filter: exact substring filtering if applicable
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
107
|
+
if substring_matches:
|
108
|
+
string_list = substring_matches
|
109
|
+
# Return all substring matches
|
110
|
+
out: list[tuple[float, str]] = []
|
111
|
+
for i, s in enumerate(string_list):
|
112
|
+
s_mapped = map_string.get(s, s)
|
113
|
+
out.append((i, s_mapped))
|
114
|
+
return out
|
80
115
|
|
81
116
|
# Third filter: in order exact match filtering if applicable.
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
is_in_order = True
|
86
|
-
break
|
87
|
-
|
88
|
-
if is_in_order:
|
89
|
-
string_list = [s for s in string_list if is_in_order_match(input_string, s)]
|
117
|
+
in_order_matches = [s for s in string_list if is_in_order_match(input_string, s)]
|
118
|
+
if in_order_matches:
|
119
|
+
string_list = in_order_matches
|
90
120
|
|
121
|
+
# Calculate distances
|
91
122
|
distances: list[float] = []
|
92
123
|
for s in string_list:
|
93
124
|
dist = fuzz.token_sort_ratio(normalize(input_string), normalize(s))
|
94
125
|
distances.append(1.0 / (dist + 1.0))
|
126
|
+
|
127
|
+
# Handle case where no strings remain after filtering
|
128
|
+
if not distances:
|
129
|
+
# Fall back to original list and calculate distances
|
130
|
+
string_list = original_string_list.copy()
|
131
|
+
if ignore_case:
|
132
|
+
string_list = [s.lower() for s in string_list]
|
133
|
+
|
134
|
+
distances = []
|
135
|
+
for s in string_list:
|
136
|
+
dist = fuzz.token_sort_ratio(normalize(input_string), normalize(s))
|
137
|
+
distances.append(1.0 / (dist + 1.0))
|
138
|
+
|
95
139
|
min_distance = min(distances)
|
96
140
|
out: list[tuple[float, str]] = []
|
97
141
|
for i, d in enumerate(distances):
|
@@ -106,10 +150,16 @@ def string_diff(
|
|
106
150
|
def string_diff_paths(
|
107
151
|
input_string: str | Path, path_list: list[Path], ignore_case=True
|
108
152
|
) -> list[tuple[float, Path]]:
|
109
|
-
|
110
|
-
|
153
|
+
# Normalize path separators to forward slashes for consistent comparison
|
154
|
+
string_list = [str(p).replace("\\", "/") for p in path_list]
|
155
|
+
input_str = str(input_string).replace("\\", "/")
|
156
|
+
|
157
|
+
tmp = string_diff(input_str, string_list, ignore_case)
|
111
158
|
out: list[tuple[float, Path]] = []
|
112
159
|
for i, j in tmp:
|
113
|
-
|
114
|
-
|
160
|
+
# Find the original path that matches the normalized result
|
161
|
+
for idx, orig_path in enumerate(path_list):
|
162
|
+
if str(orig_path).replace("\\", "/") == j:
|
163
|
+
out.append((i, orig_path))
|
164
|
+
break
|
115
165
|
return out
|
fastled/web_compile.py
CHANGED
@@ -294,8 +294,16 @@ def web_compile(
|
|
294
294
|
# Read stdout from out.txt if it exists
|
295
295
|
stdout_file = extract_path / "out.txt"
|
296
296
|
hash_file = extract_path / "hash.txt"
|
297
|
-
stdout =
|
298
|
-
|
297
|
+
stdout = (
|
298
|
+
stdout_file.read_text(encoding="utf-8", errors="replace")
|
299
|
+
if stdout_file.exists()
|
300
|
+
else ""
|
301
|
+
)
|
302
|
+
hash_value = (
|
303
|
+
hash_file.read_text(encoding="utf-8", errors="replace")
|
304
|
+
if hash_file.exists()
|
305
|
+
else None
|
306
|
+
)
|
299
307
|
|
300
308
|
# now rezip the extracted files since we added the embedded json files
|
301
309
|
out_buffer = io.BytesIO()
|
@@ -1,11 +1,12 @@
|
|
1
1
|
fastled/__init__.py,sha256=NBk5Ef65nIe0F_rvBrSGeoyouFOKFeQXqHrTCJQheeI,7201
|
2
|
-
fastled/
|
2
|
+
fastled/__main__.py,sha256=OcKv2ER1_iQAsZzLIUb3C8hRC9L2clNOhCrjpshrlf4,336
|
3
|
+
fastled/__version__.py,sha256=9FmVYi6n9qXRl6U6l1Xr9-rsxJ3ncEYDzHGxGM-sA_E,373
|
3
4
|
fastled/app.py,sha256=TFVn4qIRdt7dYbpDWudEHrhvD9pwyj9sIGXs4F26nhk,5880
|
4
5
|
fastled/args.py,sha256=kucRGYpff_YKfmMpwWsJh6WIrvW_UPcNlZNFdw15z-Y,3475
|
5
6
|
fastled/cli.py,sha256=drgR2AOxVrj3QEz58iiKscYAumbbin2vIV-k91VCOAA,561
|
6
7
|
fastled/cli_test.py,sha256=W-1nODZrip_JU6BEbYhxOa4ckxduOsiX8zIoRkTyxv4,550
|
7
8
|
fastled/cli_test_interactive.py,sha256=BjNhveZOk5aCffHbcrxPQQjWmAuj4ClVKKcKX5eY6yM,542
|
8
|
-
fastled/client_server.py,sha256=
|
9
|
+
fastled/client_server.py,sha256=2H3HBstR0kSKfLrz0LFbBIHy2WYBKc5VzhPxavhdS6o,20393
|
9
10
|
fastled/compile_server.py,sha256=yQtwLOSKINO1CKD0NWxf-7YQKSatf9sF9RuqaWGOkCs,3038
|
10
11
|
fastled/compile_server_impl.py,sha256=9vTGaDQ0W_g9Xsfy0gC3nJEc2g_pnXcF4VO2U3GLOVg,11982
|
11
12
|
fastled/docker_manager.py,sha256=rkq39ZKrU6NHIyDa3mzs0Unb6o9oMeAwxhqiuHJU_RY,40291
|
@@ -24,11 +25,11 @@ fastled/server_start.py,sha256=W9yKStkRlRNuXeV6j_6O7HjjFPyVLBHMcF9Uy2QjDWQ,479
|
|
24
25
|
fastled/settings.py,sha256=dUVyJ8Mtprg0RwaS6oMWP8jBhr4C3R8fu4Hdx_Z1lCM,577
|
25
26
|
fastled/sketch.py,sha256=Ftbh55Nt-p4hmPuPpj8Q9HrMzvnUazhoG_q9FHcxkns,3473
|
26
27
|
fastled/spinner.py,sha256=VHxmvB92P0Z_zYxRajb5HiNmkHHvZ5dG7hKtZltzpcs,867
|
27
|
-
fastled/string_diff.py,sha256=
|
28
|
+
fastled/string_diff.py,sha256=oTncu0qYdLlLUtYLLDB4bzdQ2OfzegAR6XNAzwE9fIs,6002
|
28
29
|
fastled/types.py,sha256=ZDf1TbTT4XgA_pKIwr4JbkDB38_29ogSdDORjoT-zuY,1803
|
29
30
|
fastled/util.py,sha256=TjhXbUNh4p2BGhNAldSeL68B7BBOjsWAXji5gy-vDEQ,1440
|
30
31
|
fastled/version.py,sha256=TpBMiEVdO3_sUZEu6wmwN8Q4AgX2BiCxStCsnPKh6E0,1209
|
31
|
-
fastled/web_compile.py,sha256=
|
32
|
+
fastled/web_compile.py,sha256=BPrlrW7RMAtnbYUFF3LDn0ORx7aiMOuQkSlYF_gA1o0,11867
|
32
33
|
fastled/assets/example.txt,sha256=lTBovRjiz0_TgtAtbA1C5hNi2ffbqnNPqkKg6UiKCT8,54
|
33
34
|
fastled/assets/localhost-key.pem,sha256=Q-CNO_UoOd8fFNN4ljcnqwUeCMhzTplRjLO2x0pYRlU,1704
|
34
35
|
fastled/assets/localhost.pem,sha256=QTwUtTwjYWbm9m3pHW2IlK2nFZJ8b0pppxPjhgVZqQo,1619
|
@@ -36,9 +37,9 @@ fastled/site/build.py,sha256=2YKU_UWKlJdGnjdbAbaL0co6kceFMSTVYwH1KCmgPZA,13987
|
|
36
37
|
fastled/site/examples.py,sha256=s6vj2zJc6BfKlnbwXr1QWY1mzuDBMt6j5MEBOWjO_U8,155
|
37
38
|
fastled/test/can_run_local_docker_tests.py,sha256=LEuUbHctRhNNFWcvnz2kEGmjDJeXO4c3kNpizm3yVJs,400
|
38
39
|
fastled/test/examples.py,sha256=GfaHeY1E8izBl6ZqDVjz--RHLyVR4NRnQ5pBesCFJFY,1673
|
39
|
-
fastled-1.3.
|
40
|
-
fastled-1.3.
|
41
|
-
fastled-1.3.
|
42
|
-
fastled-1.3.
|
43
|
-
fastled-1.3.
|
44
|
-
fastled-1.3.
|
40
|
+
fastled-1.3.38.dist-info/licenses/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
|
41
|
+
fastled-1.3.38.dist-info/METADATA,sha256=j0Pj8VUdX6Tvsf6r5lbEfFF9dLO0FCJLHcm3Rw7feuo,30847
|
42
|
+
fastled-1.3.38.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
43
|
+
fastled-1.3.38.dist-info/entry_points.txt,sha256=RCwmzCSOS4-C2i9EziANq7Z2Zb4KFnEMR1FQC0bBwAw,101
|
44
|
+
fastled-1.3.38.dist-info/top_level.txt,sha256=Bbv5kpJpZhWNCvDF4K0VcvtBSDMa8B7PTOrZa9CezHY,8
|
45
|
+
fastled-1.3.38.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|