M9 section S1, commit 3 — two more shared-toolkit pieces: - common.iso(dt): the "x.isoformat() if x else None" idiom (repeated 20+ times across every serializer) as one helper. Adopted in Note.serialize() and the revision serializer; other serializers adopt it in their sections. - colors.py: NOTE_COLORS (canonical, on the model) + a single normalize_color(). notes.py now imports the palette + normalizer from here and drops its local copy. labels.py's identical LABEL_COLORS/_normalize_label_color fold into this in the Organize section (S3); sync in S4. normalize_color and NOTE_COLORS remain importable from thoughtsync.notes (used by tests + sync), so nothing downstream breaks. common has no in-app imports, so the model→common→colors chain has no cycle. Behavior-preserving. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FRgehjoz7Yv8LkUfADxACm
17 lines
625 B
Python
17 lines
625 B
Python
from __future__ import annotations
|
|
|
|
from .models.note import NOTE_COLORS
|
|
|
|
# Notes and labels share one colour palette (their sets were identical). NOTE_COLORS
|
|
# is the canonical vocabulary (defined on the model); this module is the single home
|
|
# for the "clamp to the palette" normalizer so notes.py, labels.py and sync.py stop
|
|
# each carrying their own copy.
|
|
|
|
__all__ = ["NOTE_COLORS", "normalize_color"]
|
|
|
|
|
|
def normalize_color(color: object) -> str:
|
|
"""Return `color` if it's a known palette key, else the default. One definition
|
|
for both notes and labels."""
|
|
return color if color in NOTE_COLORS else "default"
|