fastled 1.2.57__py3-none-any.whl → 1.2.59__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/client_server.py +406 -406
- fastled/open_browser.py +16 -12
- fastled/open_browser2.py +14 -3
- fastled/project_init.py +129 -129
- fastled/site/build.py +449 -449
- {fastled-1.2.57.dist-info → fastled-1.2.59.dist-info}/METADATA +397 -397
- {fastled-1.2.57.dist-info → fastled-1.2.59.dist-info}/RECORD +12 -12
- {fastled-1.2.57.dist-info → fastled-1.2.59.dist-info}/WHEEL +0 -0
- {fastled-1.2.57.dist-info → fastled-1.2.59.dist-info}/entry_points.txt +0 -0
- {fastled-1.2.57.dist-info → fastled-1.2.59.dist-info}/licenses/LICENSE +0 -0
- {fastled-1.2.57.dist-info → fastled-1.2.59.dist-info}/top_level.txt +0 -0
fastled/open_browser.py
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
import subprocess
|
2
2
|
import sys
|
3
3
|
import time
|
4
|
-
import webbrowser
|
5
4
|
from multiprocessing import Process
|
6
5
|
from pathlib import Path
|
7
6
|
|
@@ -20,6 +19,9 @@ def open_http_server_subprocess(
|
|
20
19
|
port: int,
|
21
20
|
open_browser: bool,
|
22
21
|
) -> None:
|
22
|
+
print("\n################################################################")
|
23
|
+
print(f"# Opening browser to {fastled_js} on port {port}")
|
24
|
+
print("################################################################\n")
|
23
25
|
try:
|
24
26
|
# Fallback to our Python server
|
25
27
|
cmd = [
|
@@ -71,7 +73,7 @@ def is_port_free(port: int) -> bool:
|
|
71
73
|
|
72
74
|
def find_free_port(start_port: int) -> int:
|
73
75
|
"""Find a free port starting at start_port"""
|
74
|
-
for port in range(start_port, start_port + 100):
|
76
|
+
for port in range(start_port, start_port + 100, 2):
|
75
77
|
if is_port_free(port):
|
76
78
|
print(f"Found free port: {port}")
|
77
79
|
return port
|
@@ -87,7 +89,9 @@ def wait_for_server(port: int, timeout: int = 10) -> None:
|
|
87
89
|
future_time = time.time() + timeout
|
88
90
|
while future_time > time.time():
|
89
91
|
try:
|
90
|
-
|
92
|
+
url = f"http://localhost:{port}"
|
93
|
+
# print(f"Waiting for server to start at {url}")
|
94
|
+
response = get(url, timeout=1)
|
91
95
|
if response.status_code == 200:
|
92
96
|
return
|
93
97
|
except Exception:
|
@@ -113,15 +117,15 @@ def open_browser_process(
|
|
113
117
|
)
|
114
118
|
proc.start()
|
115
119
|
wait_for_server(port)
|
116
|
-
if open_browser:
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
120
|
+
# if open_browser:
|
121
|
+
# print(
|
122
|
+
# f"Opening browser to http{'s' if SSL_CONFIG.certfile else ''}://localhost:{port}"
|
123
|
+
# )
|
124
|
+
# webbrowser.open(
|
125
|
+
# url=f"http{'s' if SSL_CONFIG.certfile else ''}://localhost:{port}",
|
126
|
+
# new=1,
|
127
|
+
# autoraise=True,
|
128
|
+
# )
|
125
129
|
return proc
|
126
130
|
|
127
131
|
|
fastled/open_browser2.py
CHANGED
@@ -17,10 +17,21 @@ def get_asset_path(filename: str) -> Path | None:
|
|
17
17
|
|
18
18
|
|
19
19
|
def _open_browser(url: str) -> None:
|
20
|
-
import webview
|
20
|
+
# import webview
|
21
21
|
|
22
|
-
|
23
|
-
|
22
|
+
# print("\n##################################################")
|
23
|
+
# print(f"# Opening browser to {url}")
|
24
|
+
# print("##################################################\n")
|
25
|
+
|
26
|
+
# webview.create_window("FastLED", url)
|
27
|
+
# webview.start()
|
28
|
+
import webbrowser
|
29
|
+
|
30
|
+
webbrowser.open(url, new=1, autoraise=True)
|
31
|
+
while True:
|
32
|
+
import time
|
33
|
+
|
34
|
+
time.sleep(1)
|
24
35
|
|
25
36
|
|
26
37
|
def run(
|
fastled/project_init.py
CHANGED
@@ -1,129 +1,129 @@
|
|
1
|
-
import _thread
|
2
|
-
import threading
|
3
|
-
import time
|
4
|
-
import zipfile
|
5
|
-
from pathlib import Path
|
6
|
-
|
7
|
-
import httpx
|
8
|
-
|
9
|
-
from fastled.settings import DEFAULT_URL
|
10
|
-
from fastled.spinner import Spinner
|
11
|
-
|
12
|
-
DEFAULT_EXAMPLE = "wasm"
|
13
|
-
|
14
|
-
|
15
|
-
def get_examples(host: str | None = None) -> list[str]:
|
16
|
-
host = host or DEFAULT_URL
|
17
|
-
url_info = f"{host}/info"
|
18
|
-
response = httpx.get(url_info, timeout=4)
|
19
|
-
response.raise_for_status()
|
20
|
-
examples: list[str] = response.json()["examples"]
|
21
|
-
return sorted(examples)
|
22
|
-
|
23
|
-
|
24
|
-
def _prompt_for_example() -> str:
|
25
|
-
examples = get_examples()
|
26
|
-
while True:
|
27
|
-
print("Available examples:")
|
28
|
-
for i, example in enumerate(examples):
|
29
|
-
print(f" [{i+1}]: {example}")
|
30
|
-
answer = input("Enter the example number or name: ").strip()
|
31
|
-
if answer.isdigit():
|
32
|
-
example_num = int(answer) - 1
|
33
|
-
if example_num < 0 or example_num >= len(examples):
|
34
|
-
print("Invalid example number")
|
35
|
-
continue
|
36
|
-
return examples[example_num]
|
37
|
-
elif answer in examples:
|
38
|
-
return answer
|
39
|
-
|
40
|
-
|
41
|
-
class DownloadThread(threading.Thread):
|
42
|
-
def __init__(self, url: str, json: str):
|
43
|
-
super().__init__(daemon=True)
|
44
|
-
self.url = url
|
45
|
-
self.json = json
|
46
|
-
self.bytes_downloaded = 0
|
47
|
-
self.content: bytes | None = None
|
48
|
-
self.error: Exception | None = None
|
49
|
-
self.success = False
|
50
|
-
|
51
|
-
def run(self) -> None:
|
52
|
-
timeout = httpx.Timeout(5.0, connect=5.0, read=120.0, write=30.0)
|
53
|
-
try:
|
54
|
-
with httpx.Client(timeout=timeout) as client:
|
55
|
-
with client.stream("POST", self.url, json=self.json) as response:
|
56
|
-
response.raise_for_status()
|
57
|
-
content = b""
|
58
|
-
for chunk in response.iter_bytes():
|
59
|
-
content += chunk
|
60
|
-
self.bytes_downloaded += len(chunk)
|
61
|
-
self.content = content
|
62
|
-
self.success = True
|
63
|
-
except KeyboardInterrupt:
|
64
|
-
self.error = RuntimeError("Download cancelled")
|
65
|
-
_thread.interrupt_main()
|
66
|
-
except Exception as e:
|
67
|
-
self.error = e
|
68
|
-
|
69
|
-
|
70
|
-
def project_init(
|
71
|
-
example: str | None = "PROMPT", # prompt for example
|
72
|
-
outputdir: Path | None = None,
|
73
|
-
host: str | None = None,
|
74
|
-
) -> Path:
|
75
|
-
"""
|
76
|
-
Initialize a new FastLED project.
|
77
|
-
"""
|
78
|
-
host = host or DEFAULT_URL
|
79
|
-
outputdir = Path(outputdir) if outputdir is not None else Path("fastled")
|
80
|
-
outputdir.mkdir(exist_ok=True, parents=True)
|
81
|
-
if example == "PROMPT" or example is None:
|
82
|
-
try:
|
83
|
-
example = _prompt_for_example()
|
84
|
-
except httpx.HTTPStatusError:
|
85
|
-
print(
|
86
|
-
f"Failed to fetch examples, using default example '{DEFAULT_EXAMPLE}'"
|
87
|
-
)
|
88
|
-
example = DEFAULT_EXAMPLE
|
89
|
-
assert example is not None
|
90
|
-
endpoint_url = f"{host}/project/init"
|
91
|
-
json = example
|
92
|
-
print(f"Initializing project with example '{example}', url={endpoint_url}")
|
93
|
-
|
94
|
-
# Start download thread
|
95
|
-
download_thread = DownloadThread(endpoint_url, json)
|
96
|
-
# spinner = Spinner("Downloading project...")
|
97
|
-
with Spinner(f"Downloading project {example}..."):
|
98
|
-
download_thread.start()
|
99
|
-
while download_thread.is_alive():
|
100
|
-
time.sleep(0.1)
|
101
|
-
|
102
|
-
print() # New line after progress
|
103
|
-
download_thread.join()
|
104
|
-
|
105
|
-
# Check for errors
|
106
|
-
if not download_thread.success:
|
107
|
-
assert download_thread.error is not None
|
108
|
-
raise download_thread.error
|
109
|
-
|
110
|
-
content = download_thread.content
|
111
|
-
assert content is not None
|
112
|
-
tmpzip = outputdir / "fastled.zip"
|
113
|
-
outputdir.mkdir(exist_ok=True)
|
114
|
-
tmpzip.write_bytes(content)
|
115
|
-
with zipfile.ZipFile(tmpzip, "r") as zip_ref:
|
116
|
-
zip_ref.extractall(outputdir)
|
117
|
-
tmpzip.unlink()
|
118
|
-
out = outputdir / example
|
119
|
-
print(f"Project initialized at {out}")
|
120
|
-
assert out.exists()
|
121
|
-
return out
|
122
|
-
|
123
|
-
|
124
|
-
def unit_test() -> None:
|
125
|
-
project_init()
|
126
|
-
|
127
|
-
|
128
|
-
if __name__ == "__main__":
|
129
|
-
unit_test()
|
1
|
+
import _thread
|
2
|
+
import threading
|
3
|
+
import time
|
4
|
+
import zipfile
|
5
|
+
from pathlib import Path
|
6
|
+
|
7
|
+
import httpx
|
8
|
+
|
9
|
+
from fastled.settings import DEFAULT_URL
|
10
|
+
from fastled.spinner import Spinner
|
11
|
+
|
12
|
+
DEFAULT_EXAMPLE = "wasm"
|
13
|
+
|
14
|
+
|
15
|
+
def get_examples(host: str | None = None) -> list[str]:
|
16
|
+
host = host or DEFAULT_URL
|
17
|
+
url_info = f"{host}/info"
|
18
|
+
response = httpx.get(url_info, timeout=4)
|
19
|
+
response.raise_for_status()
|
20
|
+
examples: list[str] = response.json()["examples"]
|
21
|
+
return sorted(examples)
|
22
|
+
|
23
|
+
|
24
|
+
def _prompt_for_example() -> str:
|
25
|
+
examples = get_examples()
|
26
|
+
while True:
|
27
|
+
print("Available examples:")
|
28
|
+
for i, example in enumerate(examples):
|
29
|
+
print(f" [{i+1}]: {example}")
|
30
|
+
answer = input("Enter the example number or name: ").strip()
|
31
|
+
if answer.isdigit():
|
32
|
+
example_num = int(answer) - 1
|
33
|
+
if example_num < 0 or example_num >= len(examples):
|
34
|
+
print("Invalid example number")
|
35
|
+
continue
|
36
|
+
return examples[example_num]
|
37
|
+
elif answer in examples:
|
38
|
+
return answer
|
39
|
+
|
40
|
+
|
41
|
+
class DownloadThread(threading.Thread):
|
42
|
+
def __init__(self, url: str, json: str):
|
43
|
+
super().__init__(daemon=True)
|
44
|
+
self.url = url
|
45
|
+
self.json = json
|
46
|
+
self.bytes_downloaded = 0
|
47
|
+
self.content: bytes | None = None
|
48
|
+
self.error: Exception | None = None
|
49
|
+
self.success = False
|
50
|
+
|
51
|
+
def run(self) -> None:
|
52
|
+
timeout = httpx.Timeout(5.0, connect=5.0, read=120.0, write=30.0)
|
53
|
+
try:
|
54
|
+
with httpx.Client(timeout=timeout) as client:
|
55
|
+
with client.stream("POST", self.url, json=self.json) as response:
|
56
|
+
response.raise_for_status()
|
57
|
+
content = b""
|
58
|
+
for chunk in response.iter_bytes():
|
59
|
+
content += chunk
|
60
|
+
self.bytes_downloaded += len(chunk)
|
61
|
+
self.content = content
|
62
|
+
self.success = True
|
63
|
+
except KeyboardInterrupt:
|
64
|
+
self.error = RuntimeError("Download cancelled")
|
65
|
+
_thread.interrupt_main()
|
66
|
+
except Exception as e:
|
67
|
+
self.error = e
|
68
|
+
|
69
|
+
|
70
|
+
def project_init(
|
71
|
+
example: str | None = "PROMPT", # prompt for example
|
72
|
+
outputdir: Path | None = None,
|
73
|
+
host: str | None = None,
|
74
|
+
) -> Path:
|
75
|
+
"""
|
76
|
+
Initialize a new FastLED project.
|
77
|
+
"""
|
78
|
+
host = host or DEFAULT_URL
|
79
|
+
outputdir = Path(outputdir) if outputdir is not None else Path("fastled")
|
80
|
+
outputdir.mkdir(exist_ok=True, parents=True)
|
81
|
+
if example == "PROMPT" or example is None:
|
82
|
+
try:
|
83
|
+
example = _prompt_for_example()
|
84
|
+
except httpx.HTTPStatusError:
|
85
|
+
print(
|
86
|
+
f"Failed to fetch examples, using default example '{DEFAULT_EXAMPLE}'"
|
87
|
+
)
|
88
|
+
example = DEFAULT_EXAMPLE
|
89
|
+
assert example is not None
|
90
|
+
endpoint_url = f"{host}/project/init"
|
91
|
+
json = example
|
92
|
+
print(f"Initializing project with example '{example}', url={endpoint_url}")
|
93
|
+
|
94
|
+
# Start download thread
|
95
|
+
download_thread = DownloadThread(endpoint_url, json)
|
96
|
+
# spinner = Spinner("Downloading project...")
|
97
|
+
with Spinner(f"Downloading project {example}..."):
|
98
|
+
download_thread.start()
|
99
|
+
while download_thread.is_alive():
|
100
|
+
time.sleep(0.1)
|
101
|
+
|
102
|
+
print() # New line after progress
|
103
|
+
download_thread.join()
|
104
|
+
|
105
|
+
# Check for errors
|
106
|
+
if not download_thread.success:
|
107
|
+
assert download_thread.error is not None
|
108
|
+
raise download_thread.error
|
109
|
+
|
110
|
+
content = download_thread.content
|
111
|
+
assert content is not None
|
112
|
+
tmpzip = outputdir / "fastled.zip"
|
113
|
+
outputdir.mkdir(exist_ok=True)
|
114
|
+
tmpzip.write_bytes(content)
|
115
|
+
with zipfile.ZipFile(tmpzip, "r") as zip_ref:
|
116
|
+
zip_ref.extractall(outputdir)
|
117
|
+
tmpzip.unlink()
|
118
|
+
out = outputdir / example
|
119
|
+
print(f"Project initialized at {out}")
|
120
|
+
assert out.exists()
|
121
|
+
return out
|
122
|
+
|
123
|
+
|
124
|
+
def unit_test() -> None:
|
125
|
+
project_init()
|
126
|
+
|
127
|
+
|
128
|
+
if __name__ == "__main__":
|
129
|
+
unit_test()
|