943acbc573
Durcit la convention de nommage des projets (dérive constatée : 'Sliding Automation', 'code_versioning'... au lieu des formes canoniques). - trilium_api.py : projets_canoniques() lit le référentiel = valeurs du label projet sur les notes de type=projet (source unique, pas de constante en dur). Note-projet CodeVersioning créée (manquait). - mcp_server.py : _valider_projet() branché dans les 6 tools de création (add_decision/history/backlog, new_conversation, create_entite, add_skill). Refuse un projet non canonique (suggestion si faute) ou inconnu (renvoi au processus de création de projet). Ne verrouille pas si référentiel illisible. - lint_audit.py : VAL-nommage aligné sur le référentiel (attrape casse, espace ET snake_case ; l'ancien 'contient un espace' ratait code_versioning). - Données : 79 notes ré-étiquetées vers les 3 formes canoniques. Quality by design : l'erreur de nommage devient impossible à l'écriture, le Lint n'est plus que le filet de sécurité.
67 lines
1.8 KiB
Python
67 lines
1.8 KiB
Python
import json
|
|
import pickle
|
|
from enum import Enum
|
|
from pathlib import Path
|
|
from typing import Any, Callable, Union
|
|
|
|
from pydantic.v1.types import StrBytes
|
|
|
|
|
|
class Protocol(str, Enum):
|
|
json = 'json'
|
|
pickle = 'pickle'
|
|
|
|
|
|
def load_str_bytes(
|
|
b: StrBytes,
|
|
*,
|
|
content_type: str = None,
|
|
encoding: str = 'utf8',
|
|
proto: Protocol = None,
|
|
allow_pickle: bool = False,
|
|
json_loads: Callable[[str], Any] = json.loads,
|
|
) -> Any:
|
|
if proto is None and content_type:
|
|
if content_type.endswith(('json', 'javascript')):
|
|
pass
|
|
elif allow_pickle and content_type.endswith('pickle'):
|
|
proto = Protocol.pickle
|
|
else:
|
|
raise TypeError(f'Unknown content-type: {content_type}')
|
|
|
|
proto = proto or Protocol.json
|
|
|
|
if proto == Protocol.json:
|
|
if isinstance(b, bytes):
|
|
b = b.decode(encoding)
|
|
return json_loads(b)
|
|
elif proto == Protocol.pickle:
|
|
if not allow_pickle:
|
|
raise RuntimeError('Trying to decode with pickle with allow_pickle=False')
|
|
bb = b if isinstance(b, bytes) else b.encode()
|
|
return pickle.loads(bb)
|
|
else:
|
|
raise TypeError(f'Unknown protocol: {proto}')
|
|
|
|
|
|
def load_file(
|
|
path: Union[str, Path],
|
|
*,
|
|
content_type: str = None,
|
|
encoding: str = 'utf8',
|
|
proto: Protocol = None,
|
|
allow_pickle: bool = False,
|
|
json_loads: Callable[[str], Any] = json.loads,
|
|
) -> Any:
|
|
path = Path(path)
|
|
b = path.read_bytes()
|
|
if content_type is None:
|
|
if path.suffix in ('.js', '.json'):
|
|
proto = Protocol.json
|
|
elif path.suffix == '.pkl':
|
|
proto = Protocol.pickle
|
|
|
|
return load_str_bytes(
|
|
b, proto=proto, content_type=content_type, encoding=encoding, allow_pickle=allow_pickle, json_loads=json_loads
|
|
)
|