witbitz-code 1.2.0__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.
- witbitz_code/__init__.py +7 -0
- witbitz_code/__main__.py +3 -0
- witbitz_code/_js.py +312 -0
- witbitz_code/account.py +127 -0
- witbitz_code/asks.py +119 -0
- witbitz_code/attachments.py +266 -0
- witbitz_code/auto.py +561 -0
- witbitz_code/auto_runner.py +481 -0
- witbitz_code/cli.py +223 -0
- witbitz_code/codetools.py +128 -0
- witbitz_code/compress.py +25 -0
- witbitz_code/computers.py +189 -0
- witbitz_code/connector.py +818 -0
- witbitz_code/devicelink.py +159 -0
- witbitz_code/folders.py +250 -0
- witbitz_code/link.py +205 -0
- witbitz_code/net.py +67 -0
- witbitz_code/opencode_plugins/notes-init.md +8 -0
- witbitz_code/opencode_plugins/witbitz-media-server.mjs +791 -0
- witbitz_code/opencode_plugins/witbitz-notes.js +356 -0
- witbitz_code/opencode_plugins/witbitz-progress.js +120 -0
- witbitz_code/outputs.py +115 -0
- witbitz_code/pair.py +222 -0
- witbitz_code/pairings.py +214 -0
- witbitz_code/plugins.py +140 -0
- witbitz_code/policy.py +48 -0
- witbitz_code/qr.py +59 -0
- witbitz_code/relay.py +783 -0
- witbitz_code/seen.py +49 -0
- witbitz_code/tools_probe.py +67 -0
- witbitz_code-1.2.0.dist-info/METADATA +145 -0
- witbitz_code-1.2.0.dist-info/RECORD +36 -0
- witbitz_code-1.2.0.dist-info/WHEEL +5 -0
- witbitz_code-1.2.0.dist-info/entry_points.txt +2 -0
- witbitz_code-1.2.0.dist-info/licenses/LICENSE +21 -0
- witbitz_code-1.2.0.dist-info/top_level.txt +1 -0
witbitz_code/qr.py
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""Render the pairing challenge as a QR — tools/rc-qr.mjs. Byte mode, error correction 'M' (fixed, not boosted: it
|
|
2
|
+
survives a phone screen's glare and moiré), the smallest version that fits, a 4-module quiet zone, the same ANSI and SVG
|
|
3
|
+
output. The module pattern is segno's, not qrcode-generator's (pad codewords and mask choice differ), so the picture can
|
|
4
|
+
differ from the app's while carrying the same text — the tests decode it with the jsQR the phone runs.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
import segno
|
|
11
|
+
|
|
12
|
+
QUIET = 4 # modules of white margin; below ~4 a scanner loses the finder patterns
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def qr_modules(text: str) -> list[list[bool]]:
|
|
16
|
+
qr = segno.make(str(text), error="m", boost_error=False, micro=False, mode="byte")
|
|
17
|
+
return [[bool(bit) for bit in row] for row in qr.matrix_iter(scale=1, border=0)]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def render_ansi(rows: list[list[bool]], compact: bool | None = None) -> str:
|
|
21
|
+
"""Dark on a white background via ANSI, so it scans on a dark terminal too. Compact by default, like tools/rc-qr.mjs:
|
|
22
|
+
half blocks, one character per module across and two modules per line ("▀": top in the foreground colour, bottom in
|
|
23
|
+
the background) — a quarter of the two-spaces-per-module drawing. WITBITZ_QR=large (or compact=False) draws that one."""
|
|
24
|
+
if compact is None:
|
|
25
|
+
compact = os.environ.get("WITBITZ_QR") != "large"
|
|
26
|
+
size = len(rows)
|
|
27
|
+
dim = size + QUIET * 2
|
|
28
|
+
|
|
29
|
+
def dark(r: int, c: int) -> bool:
|
|
30
|
+
return QUIET <= r < QUIET + size and QUIET <= c < QUIET + size and bool(rows[r - QUIET][c - QUIET])
|
|
31
|
+
|
|
32
|
+
if not compact:
|
|
33
|
+
on, off = "\x1b[40m \x1b[0m", "\x1b[47m \x1b[0m"
|
|
34
|
+
return "\n".join("".join(on if dark(r, c) else off for c in range(dim)) for r in range(dim))
|
|
35
|
+
lines = []
|
|
36
|
+
for r in range(0, dim, 2):
|
|
37
|
+
cells = "".join(f"\x1b[{30 if dark(r, c) else 97};{40 if dark(r + 1, c) else 107}m▀" for c in range(dim))
|
|
38
|
+
lines.append(cells + "\x1b[0m")
|
|
39
|
+
return "\n".join(lines)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def render_svg(rows: list[list[bool]], px: int = 320) -> str:
|
|
43
|
+
"""Black modules on white with the quiet zone — open or scan it on any device."""
|
|
44
|
+
dim = len(rows) + QUIET * 2
|
|
45
|
+
rects = "".join(
|
|
46
|
+
f'<rect x="{c + QUIET}" y="{r + QUIET}" width="1" height="1"/>'
|
|
47
|
+
for r, row in enumerate(rows) for c, d in enumerate(row) if d
|
|
48
|
+
)
|
|
49
|
+
return (f'<svg xmlns="http://www.w3.org/2000/svg" width="{px}" height="{px}" viewBox="0 0 {dim} {dim}" '
|
|
50
|
+
f'shape-rendering="crispEdges" role="img" aria-label="Pairing QR">'
|
|
51
|
+
f'<rect width="{dim}" height="{dim}" fill="#fff"/><g fill="#000">{rects}</g></svg>')
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def qr_ansi(text: str) -> str:
|
|
55
|
+
return render_ansi(qr_modules(text))
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def qr_svg(text: str, px: int = 320) -> str:
|
|
59
|
+
return render_svg(qr_modules(text), px)
|