host.camera_visualizer.routes.points

Field measurement point persistence with named sets.

 1"""Field measurement point persistence with named sets."""
 2
 3import json
 4import os
 5import re
 6
 7
 8def _safe_name(name: str) -> str:
 9    """Sanitize set name for use as filename."""
10    return re.sub(r'[^a-zA-Z0-9_-]', '_', name)
11
12
13def _set_path(points_dir: str, set_name: str) -> str:
14    """Get the file path for a named point set."""
15    safe = _safe_name(set_name)
16    return os.path.join(points_dir, f'{safe}.json')
17
18
19def load_points(points_dir: str, set_name: str = 'default') -> str:
20    """Read saved points for a named set. Returns JSON string."""
21    fpath = _set_path(points_dir, set_name)
22    if os.path.isfile(fpath):
23        with open(fpath, 'r') as f:
24            return f.read()
25    return '{"name":"' + set_name + '","points":[]}'
26
27
28def save_points(points_dir: str, set_name: str, data: bytes) -> None:
29    """Write points data to a named set file."""
30    os.makedirs(points_dir, exist_ok=True)
31    fpath = _set_path(points_dir, set_name)
32    with open(fpath, 'wb') as f:
33        f.write(data)
34
35
36def list_point_sets(points_dir: str) -> list:
37    """List available point set names."""
38    sets = []
39    if os.path.isdir(points_dir):
40        for fname in sorted(os.listdir(points_dir)):
41            if fname.endswith('.json'):
42                name = fname[:-5]
43                fpath = os.path.join(points_dir, fname)
44                try:
45                    with open(fpath, 'r') as f:
46                        data = json.load(f)
47                    sets.append({
48                        'name': data.get('name', name),
49                        'file': name,
50                        'count': len(data.get('points', [])),
51                    })
52                except (json.JSONDecodeError, OSError):
53                    sets.append({'name': name, 'file': name, 'count': 0})
54    return sets
def load_points(points_dir: str, set_name: str = 'default') -> str:
20def load_points(points_dir: str, set_name: str = 'default') -> str:
21    """Read saved points for a named set. Returns JSON string."""
22    fpath = _set_path(points_dir, set_name)
23    if os.path.isfile(fpath):
24        with open(fpath, 'r') as f:
25            return f.read()
26    return '{"name":"' + set_name + '","points":[]}'

Read saved points for a named set. Returns JSON string.

def save_points(points_dir: str, set_name: str, data: bytes) -> None:
29def save_points(points_dir: str, set_name: str, data: bytes) -> None:
30    """Write points data to a named set file."""
31    os.makedirs(points_dir, exist_ok=True)
32    fpath = _set_path(points_dir, set_name)
33    with open(fpath, 'wb') as f:
34        f.write(data)

Write points data to a named set file.

def list_point_sets(points_dir: str) -> list:
37def list_point_sets(points_dir: str) -> list:
38    """List available point set names."""
39    sets = []
40    if os.path.isdir(points_dir):
41        for fname in sorted(os.listdir(points_dir)):
42            if fname.endswith('.json'):
43                name = fname[:-5]
44                fpath = os.path.join(points_dir, fname)
45                try:
46                    with open(fpath, 'r') as f:
47                        data = json.load(f)
48                    sets.append({
49                        'name': data.get('name', name),
50                        'file': name,
51                        'count': len(data.get('points', [])),
52                    })
53                except (json.JSONDecodeError, OSError):
54                    sets.append({'name': name, 'file': name, 'count': 0})
55    return sets

List available point set names.