fastled 1.1.17__py2.py3-none-any.whl → 1.1.19__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 +1 -1
- fastled/app.py +55 -28
- fastled/docker_manager.py +5 -8
- fastled/filewatcher.py +202 -196
- fastled/sketch.py +25 -4
- {fastled-1.1.17.dist-info → fastled-1.1.19.dist-info}/METADATA +3 -1
- {fastled-1.1.17.dist-info → fastled-1.1.19.dist-info}/RECORD +11 -11
- {fastled-1.1.17.dist-info → fastled-1.1.19.dist-info}/LICENSE +0 -0
- {fastled-1.1.17.dist-info → fastled-1.1.19.dist-info}/WHEEL +0 -0
- {fastled-1.1.17.dist-info → fastled-1.1.19.dist-info}/entry_points.txt +0 -0
- {fastled-1.1.17.dist-info → fastled-1.1.19.dist-info}/top_level.txt +0 -0
fastled/__init__.py
CHANGED
fastled/app.py
CHANGED
@@ -20,7 +20,11 @@ from fastled.docker_manager import DockerManager
|
|
20
20
|
from fastled.filewatcher import FileWatcherProcess
|
21
21
|
from fastled.keyboard import SpaceBarWatcher
|
22
22
|
from fastled.open_browser import open_browser_thread
|
23
|
-
from fastled.sketch import
|
23
|
+
from fastled.sketch import (
|
24
|
+
find_sketch_directories,
|
25
|
+
looks_like_fastled_repo,
|
26
|
+
looks_like_sketch_directory,
|
27
|
+
)
|
24
28
|
from fastled.web_compile import (
|
25
29
|
SERVER_PORT,
|
26
30
|
ConnectionResult,
|
@@ -82,28 +86,6 @@ def parse_args() -> argparse.Namespace:
|
|
82
86
|
action="store_true",
|
83
87
|
help="Enable profiling for web compilation",
|
84
88
|
)
|
85
|
-
build_mode = parser.add_mutually_exclusive_group()
|
86
|
-
build_mode.add_argument("--debug", action="store_true", help="Build in debug mode")
|
87
|
-
build_mode.add_argument(
|
88
|
-
"--quick",
|
89
|
-
action="store_true",
|
90
|
-
default=True,
|
91
|
-
help="Build in quick mode (default)",
|
92
|
-
)
|
93
|
-
build_mode.add_argument(
|
94
|
-
"--release", action="store_true", help="Build in release mode"
|
95
|
-
)
|
96
|
-
build_mode.add_argument(
|
97
|
-
"--localhost",
|
98
|
-
"--local",
|
99
|
-
action="store_true",
|
100
|
-
help="Use localhost for web compilation from an instance of fastled --server, creating it if necessary",
|
101
|
-
)
|
102
|
-
build_mode.add_argument(
|
103
|
-
"--server",
|
104
|
-
action="store_true",
|
105
|
-
help="Run the server in the current directory, volume mapping fastled if we are in the repo",
|
106
|
-
)
|
107
89
|
parser.add_argument(
|
108
90
|
"--force-compile",
|
109
91
|
action="store_true",
|
@@ -119,6 +101,30 @@ def parse_args() -> argparse.Namespace:
|
|
119
101
|
action="store_true",
|
120
102
|
help="Update the wasm compiler (if necessary) before running",
|
121
103
|
)
|
104
|
+
parser.add_argument(
|
105
|
+
"--localhost",
|
106
|
+
"--local",
|
107
|
+
"-l",
|
108
|
+
action="store_true",
|
109
|
+
help="Use localhost for web compilation from an instance of fastled --server, creating it if necessary",
|
110
|
+
)
|
111
|
+
parser.add_argument(
|
112
|
+
"--server",
|
113
|
+
"-s",
|
114
|
+
action="store_true",
|
115
|
+
help="Run the server in the current directory, volume mapping fastled if we are in the repo",
|
116
|
+
)
|
117
|
+
build_mode = parser.add_mutually_exclusive_group()
|
118
|
+
build_mode.add_argument("--debug", action="store_true", help="Build in debug mode")
|
119
|
+
build_mode.add_argument(
|
120
|
+
"--quick",
|
121
|
+
action="store_true",
|
122
|
+
default=True,
|
123
|
+
help="Build in quick mode (default)",
|
124
|
+
)
|
125
|
+
build_mode.add_argument(
|
126
|
+
"--release", action="store_true", help="Build in release mode"
|
127
|
+
)
|
122
128
|
|
123
129
|
cwd_is_fastled = looks_like_fastled_repo(Path(os.getcwd()))
|
124
130
|
|
@@ -133,7 +139,7 @@ def parse_args() -> argparse.Namespace:
|
|
133
139
|
if not cwd_is_fastled and not args.localhost and not args.web and not args.server:
|
134
140
|
print(f"Using web compiler at {DEFAULT_URL}")
|
135
141
|
args.web = DEFAULT_URL
|
136
|
-
if cwd_is_fastled and not args.web:
|
142
|
+
if cwd_is_fastled and not args.web and not args.server:
|
137
143
|
print("Forcing --local mode because we are in the FastLED repo")
|
138
144
|
args.localhost = True
|
139
145
|
if args.localhost:
|
@@ -147,10 +153,31 @@ def parse_args() -> argparse.Namespace:
|
|
147
153
|
if looks_like_sketch_directory(maybe_sketch_dir):
|
148
154
|
args.directory = str(maybe_sketch_dir)
|
149
155
|
else:
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
156
|
+
sketch_directories = find_sketch_directories(maybe_sketch_dir)
|
157
|
+
if len(sketch_directories) == 1:
|
158
|
+
print(f"\nUsing sketch directory: {sketch_directories[0]}")
|
159
|
+
args.directory = str(sketch_directories[0])
|
160
|
+
elif len(sketch_directories) > 1:
|
161
|
+
print("\nMultiple Directories found, choose one:")
|
162
|
+
for i, sketch_dir in enumerate(sketch_directories):
|
163
|
+
print(f" [{i+1}]: {sketch_dir}")
|
164
|
+
which = input("\nPlease specify a sketch directory: ")
|
165
|
+
try:
|
166
|
+
index = int(which) - 1
|
167
|
+
args.directory = str(sketch_directories[index])
|
168
|
+
except (ValueError, IndexError):
|
169
|
+
print("Invalid selection.")
|
170
|
+
sys.exit(1)
|
171
|
+
else:
|
172
|
+
print(
|
173
|
+
"\nYou either need to specify a sketch directory or run in --server mode."
|
174
|
+
)
|
175
|
+
sys.exit(1)
|
176
|
+
elif args.directory is not None and os.path.isfile(args.directory):
|
177
|
+
dir_path = Path(args.directory).parent
|
178
|
+
if looks_like_sketch_directory(dir_path):
|
179
|
+
print(f"Using sketch directory: {dir_path}")
|
180
|
+
args.directory = str(dir_path)
|
154
181
|
|
155
182
|
return args
|
156
183
|
|
fastled/docker_manager.py
CHANGED
@@ -176,6 +176,8 @@ class DockerManager:
|
|
176
176
|
If upgrade is True, will pull the latest version even if image exists locally.
|
177
177
|
"""
|
178
178
|
print(f"Validating image {image_name}:{tag}...")
|
179
|
+
remote_image_hash_from_local_image: str | None = None
|
180
|
+
remote_image_hash: str | None = None
|
179
181
|
|
180
182
|
with get_lock(f"{image_name}-{tag}"):
|
181
183
|
try:
|
@@ -187,7 +189,7 @@ class DockerManager:
|
|
187
189
|
f"{image_name}:{tag}"
|
188
190
|
)
|
189
191
|
remote_image_hash = remote_image.id
|
190
|
-
|
192
|
+
|
191
193
|
try:
|
192
194
|
remote_image_hash_from_local_image = DISK_CACHE.get(
|
193
195
|
local_image.id
|
@@ -196,9 +198,6 @@ class DockerManager:
|
|
196
198
|
raise
|
197
199
|
except Exception:
|
198
200
|
remote_image_hash_from_local_image = None
|
199
|
-
import traceback
|
200
|
-
import warnings
|
201
|
-
|
202
201
|
stack = traceback.format_exc()
|
203
202
|
warnings.warn(
|
204
203
|
f"Error getting remote image hash from local image: {stack}"
|
@@ -213,7 +212,8 @@ class DockerManager:
|
|
213
212
|
_ = self.client.images.pull(image_name, tag=tag)
|
214
213
|
print(f"Updated to newer version of {image_name}:{tag}")
|
215
214
|
local_image_hash = self.client.images.get(f"{image_name}:{tag}").id
|
216
|
-
|
215
|
+
if remote_image_hash is not None:
|
216
|
+
DISK_CACHE.put(local_image_hash, remote_image_hash)
|
217
217
|
|
218
218
|
except docker.errors.ImageNotFound:
|
219
219
|
print(f"Image {image_name}:{tag} not found. Downloading...")
|
@@ -221,11 +221,8 @@ class DockerManager:
|
|
221
221
|
try:
|
222
222
|
local_image = self.client.images.get(f"{image_name}:{tag}")
|
223
223
|
local_image_hash = local_image.id
|
224
|
-
DISK_CACHE.put(local_image_hash, remote_image_hash)
|
225
224
|
print(f"Image {image_name}:{tag} downloaded successfully.")
|
226
225
|
except docker.errors.ImageNotFound:
|
227
|
-
import warnings
|
228
|
-
|
229
226
|
warnings.warn(f"Image {image_name}:{tag} not found after download.")
|
230
227
|
|
231
228
|
def tag_image(self, image_name: str, old_tag: str, new_tag: str) -> None:
|
fastled/filewatcher.py
CHANGED
@@ -1,196 +1,202 @@
|
|
1
|
-
"""File system watcher implementation using watchdog
|
2
|
-
"""
|
3
|
-
|
4
|
-
import hashlib
|
5
|
-
import os
|
6
|
-
import queue
|
7
|
-
import threading
|
8
|
-
import time
|
9
|
-
from contextlib import redirect_stdout
|
10
|
-
from multiprocessing import Process, Queue
|
11
|
-
from pathlib import Path
|
12
|
-
from queue import Empty
|
13
|
-
from typing import Dict, Set
|
14
|
-
|
15
|
-
from watchdog.events import FileSystemEvent, FileSystemEventHandler
|
16
|
-
from watchdog.observers import Observer
|
17
|
-
from watchdog.observers.api import BaseObserver
|
18
|
-
|
19
|
-
|
20
|
-
class MyEventHandler(FileSystemEventHandler):
|
21
|
-
def __init__(
|
22
|
-
self,
|
23
|
-
change_queue: queue.Queue,
|
24
|
-
excluded_patterns: Set[str],
|
25
|
-
file_hashes: Dict[str, str],
|
26
|
-
) -> None:
|
27
|
-
super().__init__()
|
28
|
-
self.change_queue = change_queue
|
29
|
-
self.excluded_patterns = excluded_patterns
|
30
|
-
self.file_hashes = file_hashes
|
31
|
-
|
32
|
-
def _get_file_hash(self, filepath: str) -> str:
|
33
|
-
try:
|
34
|
-
with open(filepath, "rb") as f:
|
35
|
-
return hashlib.md5(f.read()).hexdigest()
|
36
|
-
except Exception: # pylint: disable=broad-except
|
37
|
-
return ""
|
38
|
-
|
39
|
-
def on_modified(self, event: FileSystemEvent) -> None:
|
40
|
-
if not event.is_directory:
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
"""
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
self.
|
76
|
-
|
77
|
-
|
78
|
-
self.
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
self.
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
self.
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
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
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
self.
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
self.
|
185
|
-
|
186
|
-
def
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
1
|
+
"""File system watcher implementation using watchdog
|
2
|
+
"""
|
3
|
+
|
4
|
+
import hashlib
|
5
|
+
import os
|
6
|
+
import queue
|
7
|
+
import threading
|
8
|
+
import time
|
9
|
+
from contextlib import redirect_stdout
|
10
|
+
from multiprocessing import Process, Queue
|
11
|
+
from pathlib import Path
|
12
|
+
from queue import Empty
|
13
|
+
from typing import Dict, Set
|
14
|
+
|
15
|
+
from watchdog.events import FileSystemEvent, FileSystemEventHandler
|
16
|
+
from watchdog.observers import Observer
|
17
|
+
from watchdog.observers.api import BaseObserver
|
18
|
+
|
19
|
+
|
20
|
+
class MyEventHandler(FileSystemEventHandler):
|
21
|
+
def __init__(
|
22
|
+
self,
|
23
|
+
change_queue: queue.Queue,
|
24
|
+
excluded_patterns: Set[str],
|
25
|
+
file_hashes: Dict[str, str],
|
26
|
+
) -> None:
|
27
|
+
super().__init__()
|
28
|
+
self.change_queue = change_queue
|
29
|
+
self.excluded_patterns = excluded_patterns
|
30
|
+
self.file_hashes = file_hashes
|
31
|
+
|
32
|
+
def _get_file_hash(self, filepath: str) -> str:
|
33
|
+
try:
|
34
|
+
with open(filepath, "rb") as f:
|
35
|
+
return hashlib.md5(f.read()).hexdigest()
|
36
|
+
except Exception: # pylint: disable=broad-except
|
37
|
+
return ""
|
38
|
+
|
39
|
+
def on_modified(self, event: FileSystemEvent) -> None:
|
40
|
+
if not event.is_directory:
|
41
|
+
# Convert src_path to str if it's bytes
|
42
|
+
src_path = (
|
43
|
+
event.src_path.decode()
|
44
|
+
if isinstance(event.src_path, bytes)
|
45
|
+
else event.src_path
|
46
|
+
)
|
47
|
+
path = Path(src_path)
|
48
|
+
# Check if any part of the path matches excluded patterns
|
49
|
+
if not any(part in self.excluded_patterns for part in path.parts):
|
50
|
+
new_hash = self._get_file_hash(src_path)
|
51
|
+
if new_hash and new_hash != self.file_hashes.get(src_path):
|
52
|
+
self.file_hashes[src_path] = new_hash
|
53
|
+
self.change_queue.put(src_path)
|
54
|
+
|
55
|
+
|
56
|
+
class FileChangedNotifier(threading.Thread):
|
57
|
+
"""Watches a directory for file changes and queues notifications"""
|
58
|
+
|
59
|
+
def __init__(
|
60
|
+
self,
|
61
|
+
path: str,
|
62
|
+
debounce_seconds: float = 1.0,
|
63
|
+
excluded_patterns: list[str] | None = None,
|
64
|
+
) -> None:
|
65
|
+
"""Initialize the notifier with a path to watch
|
66
|
+
|
67
|
+
Args:
|
68
|
+
path: Directory path to watch for changes
|
69
|
+
debounce_seconds: Minimum time between notifications for the same file
|
70
|
+
excluded_patterns: List of directory/file patterns to exclude from watching
|
71
|
+
"""
|
72
|
+
super().__init__(daemon=True)
|
73
|
+
self.path = path
|
74
|
+
self.observer: BaseObserver | None = None
|
75
|
+
self.event_handler: MyEventHandler | None = None
|
76
|
+
|
77
|
+
# Combine default and user-provided patterns
|
78
|
+
self.excluded_patterns = (
|
79
|
+
set(excluded_patterns) if excluded_patterns is not None else set()
|
80
|
+
)
|
81
|
+
self.stopped = False
|
82
|
+
self.change_queue: queue.Queue = queue.Queue()
|
83
|
+
self.last_notification: Dict[str, float] = {}
|
84
|
+
self.file_hashes: Dict[str, str] = {}
|
85
|
+
self.debounce_seconds = debounce_seconds
|
86
|
+
|
87
|
+
def stop(self) -> None:
|
88
|
+
"""Stop watching for changes"""
|
89
|
+
print("watcher stop")
|
90
|
+
self.stopped = True
|
91
|
+
if self.observer:
|
92
|
+
self.observer.stop()
|
93
|
+
self.observer.join()
|
94
|
+
self.observer = None
|
95
|
+
self.event_handler = None
|
96
|
+
|
97
|
+
def run(self) -> None:
|
98
|
+
"""Thread main loop - starts watching for changes"""
|
99
|
+
self.event_handler = MyEventHandler(
|
100
|
+
self.change_queue, self.excluded_patterns, self.file_hashes
|
101
|
+
)
|
102
|
+
self.observer = Observer()
|
103
|
+
self.observer.schedule(self.event_handler, self.path, recursive=True)
|
104
|
+
self.observer.start()
|
105
|
+
|
106
|
+
try:
|
107
|
+
while not self.stopped:
|
108
|
+
time.sleep(0.1)
|
109
|
+
except KeyboardInterrupt:
|
110
|
+
print("File watcher stopped by user.")
|
111
|
+
finally:
|
112
|
+
self.stop()
|
113
|
+
|
114
|
+
def get_next_change(self, timeout: float = 0.001) -> str | None:
|
115
|
+
"""Get the next file change event from the queue
|
116
|
+
|
117
|
+
Args:
|
118
|
+
timeout: How long to wait for next change in seconds
|
119
|
+
|
120
|
+
Returns:
|
121
|
+
Changed filepath or None if no change within timeout
|
122
|
+
"""
|
123
|
+
try:
|
124
|
+
filepath = self.change_queue.get(timeout=timeout)
|
125
|
+
current_time = time.time()
|
126
|
+
|
127
|
+
# Check if we've seen this file recently
|
128
|
+
last_time = self.last_notification.get(filepath, 0)
|
129
|
+
if current_time - last_time < self.debounce_seconds:
|
130
|
+
return None
|
131
|
+
|
132
|
+
self.last_notification[filepath] = current_time
|
133
|
+
return filepath
|
134
|
+
except KeyboardInterrupt:
|
135
|
+
raise
|
136
|
+
except queue.Empty:
|
137
|
+
return None
|
138
|
+
|
139
|
+
def get_all_changes(self, timeout: float = 0.001) -> list[str]:
|
140
|
+
"""Get all file change events from the queue
|
141
|
+
|
142
|
+
Args:
|
143
|
+
timeout: How long to wait for next change in seconds
|
144
|
+
|
145
|
+
Returns:
|
146
|
+
List of changed filepaths
|
147
|
+
"""
|
148
|
+
changed_files = []
|
149
|
+
while True:
|
150
|
+
changed_file = self.get_next_change(timeout=timeout)
|
151
|
+
if changed_file is None:
|
152
|
+
break
|
153
|
+
changed_files.append(changed_file)
|
154
|
+
# clear all the changes from the queue
|
155
|
+
self.change_queue.queue.clear()
|
156
|
+
return changed_files
|
157
|
+
|
158
|
+
|
159
|
+
def _process_wrapper(root: Path, excluded_patterns: list[str], queue: Queue):
|
160
|
+
with open(os.devnull, "w") as fnull: # Redirect to /dev/null
|
161
|
+
with redirect_stdout(fnull):
|
162
|
+
watcher = FileChangedNotifier(
|
163
|
+
str(root), excluded_patterns=excluded_patterns
|
164
|
+
)
|
165
|
+
watcher.start()
|
166
|
+
while True:
|
167
|
+
try:
|
168
|
+
changed_files = watcher.get_all_changes()
|
169
|
+
for file in changed_files:
|
170
|
+
queue.put(file)
|
171
|
+
except KeyboardInterrupt:
|
172
|
+
break
|
173
|
+
watcher.stop()
|
174
|
+
|
175
|
+
|
176
|
+
class FileWatcherProcess:
|
177
|
+
def __init__(self, root: Path, excluded_patterns: list[str]) -> None:
|
178
|
+
self.queue: Queue = Queue()
|
179
|
+
self.process = Process(
|
180
|
+
target=_process_wrapper,
|
181
|
+
args=(root, excluded_patterns, self.queue),
|
182
|
+
daemon=True,
|
183
|
+
)
|
184
|
+
self.process.start()
|
185
|
+
|
186
|
+
def stop(self):
|
187
|
+
self.process.terminate()
|
188
|
+
self.process.join()
|
189
|
+
self.queue.close()
|
190
|
+
self.queue.join_thread()
|
191
|
+
|
192
|
+
def get_all_changes(self, timeout: float | None = None) -> list[str]:
|
193
|
+
changed_files = []
|
194
|
+
block = timeout is not None
|
195
|
+
|
196
|
+
while True:
|
197
|
+
try:
|
198
|
+
changed_file = self.queue.get(block=block, timeout=timeout)
|
199
|
+
changed_files.append(changed_file)
|
200
|
+
except Empty:
|
201
|
+
break
|
202
|
+
return changed_files
|
fastled/sketch.py
CHANGED
@@ -2,6 +2,27 @@ import os
|
|
2
2
|
from pathlib import Path
|
3
3
|
|
4
4
|
|
5
|
+
def find_sketch_directories(directory: Path) -> list[Path]:
|
6
|
+
sketch_directories: list[Path] = []
|
7
|
+
# search all the paths one level deep
|
8
|
+
for path in directory.iterdir():
|
9
|
+
if path.is_dir():
|
10
|
+
dir_name = path.name
|
11
|
+
if str(dir_name).startswith("."):
|
12
|
+
continue
|
13
|
+
|
14
|
+
if looks_like_sketch_directory(path, quick=True):
|
15
|
+
sketch_directories.append(path)
|
16
|
+
if dir_name.lower() == "examples":
|
17
|
+
for example in path.iterdir():
|
18
|
+
if example.is_dir():
|
19
|
+
if looks_like_sketch_directory(example, quick=True):
|
20
|
+
sketch_directories.append(example)
|
21
|
+
# make relative to cwd
|
22
|
+
sketch_directories = [p.relative_to(directory) for p in sketch_directories]
|
23
|
+
return sketch_directories
|
24
|
+
|
25
|
+
|
5
26
|
def get_sketch_files(directory: Path) -> list[Path]:
|
6
27
|
files: list[Path] = []
|
7
28
|
for root, dirs, filenames in os.walk(directory):
|
@@ -30,14 +51,14 @@ def _lots_and_lots_of_files(directory: Path) -> bool:
|
|
30
51
|
return len(get_sketch_files(directory)) > 100
|
31
52
|
|
32
53
|
|
33
|
-
def looks_like_sketch_directory(directory: Path) -> bool:
|
54
|
+
def looks_like_sketch_directory(directory: Path, quick=False) -> bool:
|
34
55
|
if looks_like_fastled_repo(directory):
|
35
56
|
print("Directory looks like the FastLED repo")
|
36
57
|
return False
|
37
58
|
|
38
|
-
if
|
39
|
-
|
40
|
-
|
59
|
+
if not quick:
|
60
|
+
if _lots_and_lots_of_files(directory):
|
61
|
+
return False
|
41
62
|
|
42
63
|
# walk the path and if there are over 30 files, return False
|
43
64
|
# at the root of the directory there should either be an ino file or a src directory
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: fastled
|
3
|
-
Version: 1.1.
|
3
|
+
Version: 1.1.19
|
4
4
|
Summary: FastLED Wasm Compiler
|
5
5
|
Home-page: https://github.com/zackees/fastled-wasm
|
6
6
|
Maintainer: Zachary Vorhies
|
@@ -161,6 +161,8 @@ A: A big chunk of space is being used by unnecessary javascript `emscripten` is
|
|
161
161
|
|
162
162
|
# Revisions
|
163
163
|
|
164
|
+
* 1.1.19 - Automatically does a limit searches for sketch directories if you leave it blank.
|
165
|
+
* 1.1.18 - Fixes for when the image has never been downloaded.
|
164
166
|
* 1.1.17 - Added `--update` and `--no-auto-update` to control whether the compiler in docker mode will try to update.
|
165
167
|
* 1.1.16 - Rewrote docker logic to use container suspension and resumption. Much much faster.
|
166
168
|
* 1.1.15 - Fixed logic for considering ipv6 addresses. Auto selection of ipv6 is now restored.
|
@@ -1,20 +1,20 @@
|
|
1
|
-
fastled/__init__.py,sha256=
|
2
|
-
fastled/app.py,sha256=
|
1
|
+
fastled/__init__.py,sha256=S0nyYWk7HxAJsrOn1JMsxyV2GhDT9lICQ3IDATqujh8,64
|
2
|
+
fastled/app.py,sha256=GuYL67fzR7iifJ6zwd023KeXRHwOSv8Uliz9ZNmFy9A,16903
|
3
3
|
fastled/build_mode.py,sha256=joMwsV4K1y_LijT4gEAcjx69RZBoe_KmFmHZdPYbL_4,631
|
4
4
|
fastled/cli.py,sha256=CNR_pQR0sNVPNuv8e_nmm-0PI8sU-eUBUgnWgWkzW9c,237
|
5
5
|
fastled/compile_server.py,sha256=aBdpILSRrDsCJ5e9g5uwIqt9bcqE_8FrSddCV2ygtrI,5401
|
6
|
-
fastled/docker_manager.py,sha256=
|
7
|
-
fastled/filewatcher.py,sha256=
|
6
|
+
fastled/docker_manager.py,sha256=AzQBXqWB1Uq_Qb1mp1NS4hIbkC8aYp-pzpYhFRpI5ww,19940
|
7
|
+
fastled/filewatcher.py,sha256=5dVmjEG23kMeJa29tRVm5XKSr9sTD4ME2boo-CFDuUM,6910
|
8
8
|
fastled/keyboard.py,sha256=rqndglWYzRy6oiqHgsmx1peLd0Yrpci01zGENlCzh_s,2576
|
9
9
|
fastled/open_browser.py,sha256=RRHcsZ5Vzsw1AuZUEYuSfjKmf_9j3NGMDUR-FndHmqs,1483
|
10
10
|
fastled/paths.py,sha256=VsPmgu0lNSCFOoEC0BsTYzDygXqy15AHUfN-tTuzDZA,99
|
11
|
-
fastled/sketch.py,sha256=
|
11
|
+
fastled/sketch.py,sha256=5nRjg281lMH8Bo9wKjbcpTQCfEP574ZCG-lukvFmyQ8,2656
|
12
12
|
fastled/util.py,sha256=t4M3NFMhnCzfYbLvIyJi0RdFssZqbTN_vVIaej1WV-U,265
|
13
13
|
fastled/web_compile.py,sha256=KuvKGdX6SSUUqC7YgX4T9SMSP5wdcPUhpg9-K9zPoTI,10378
|
14
14
|
fastled/assets/example.txt,sha256=lTBovRjiz0_TgtAtbA1C5hNi2ffbqnNPqkKg6UiKCT8,54
|
15
|
-
fastled-1.1.
|
16
|
-
fastled-1.1.
|
17
|
-
fastled-1.1.
|
18
|
-
fastled-1.1.
|
19
|
-
fastled-1.1.
|
20
|
-
fastled-1.1.
|
15
|
+
fastled-1.1.19.dist-info/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
|
16
|
+
fastled-1.1.19.dist-info/METADATA,sha256=zW3vY83mwHyd8N76_rzBcu1YwEU-HEgdYBRoliVonoY,13658
|
17
|
+
fastled-1.1.19.dist-info/WHEEL,sha256=0VNUDWQJzfRahYI3neAhz2UVbRCtztpN5dPHAGvmGXc,109
|
18
|
+
fastled-1.1.19.dist-info/entry_points.txt,sha256=RCwmzCSOS4-C2i9EziANq7Z2Zb4KFnEMR1FQC0bBwAw,101
|
19
|
+
fastled-1.1.19.dist-info/top_level.txt,sha256=xfG6Z_ol9V5YmBROkZq2QTRwjbS2ouCUxaTJsOwfkOo,14
|
20
|
+
fastled-1.1.19.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|