feat(ui): pattern modes, bundles, and zone content kind
Add profile/preset/sequence JSON import and export; map preset mode to wire n6 with a mode dropdown for multi-mode patterns; zone edit shows presets or sequences only with content_kind on save; update catalogue and tests for merged pattern names. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -3,11 +3,14 @@ from microdot.session import with_session
|
||||
from models.sequence import Sequence
|
||||
from models.profile import Profile
|
||||
from models.transport import get_current_sender
|
||||
from models.preset import Preset
|
||||
from util.profile_bundle import export_sequence_bundle, import_sequence_bundle
|
||||
import json
|
||||
|
||||
controller = Microdot()
|
||||
sequences = Sequence()
|
||||
profiles = Profile()
|
||||
presets = Preset()
|
||||
|
||||
|
||||
def get_current_profile_id(session=None):
|
||||
@@ -39,6 +42,57 @@ async def list_sequences(request, session):
|
||||
return json.dumps(scoped), 200, {"Content-Type": "application/json"}
|
||||
|
||||
|
||||
@controller.get("/<id>/export")
|
||||
@with_session
|
||||
async def export_sequence(request, session, id):
|
||||
"""Export a sequence and referenced presets as a JSON bundle."""
|
||||
current_profile_id = get_current_profile_id(session)
|
||||
if not current_profile_id:
|
||||
return json.dumps({"error": "No profile available"}), 404, {"Content-Type": "application/json"}
|
||||
try:
|
||||
bundle = export_sequence_bundle(
|
||||
id,
|
||||
sequences,
|
||||
presets,
|
||||
profile_id=current_profile_id,
|
||||
)
|
||||
return json.dumps(bundle), 200, {"Content-Type": "application/json"}
|
||||
except ValueError as e:
|
||||
return json.dumps({"error": str(e)}), 404, {"Content-Type": "application/json"}
|
||||
|
||||
|
||||
@controller.post("/import")
|
||||
@with_session
|
||||
async def import_sequence(request, session):
|
||||
"""Import a sequence bundle into the current profile."""
|
||||
try:
|
||||
current_profile_id = get_current_profile_id(session)
|
||||
if not current_profile_id:
|
||||
return (
|
||||
json.dumps({"error": "No profile available"}),
|
||||
404,
|
||||
{"Content-Type": "application/json"},
|
||||
)
|
||||
body = request.json or {}
|
||||
bundle = body.get("bundle") if isinstance(body, dict) else body
|
||||
if not isinstance(bundle, dict):
|
||||
return (
|
||||
json.dumps({"error": "Expected JSON bundle"}),
|
||||
400,
|
||||
{"Content-Type": "application/json"},
|
||||
)
|
||||
new_id, seq_data = import_sequence_bundle(bundle, sequences, presets, current_profile_id)
|
||||
return (
|
||||
json.dumps({new_id: seq_data}),
|
||||
201,
|
||||
{"Content-Type": "application/json"},
|
||||
)
|
||||
except ValueError as e:
|
||||
return json.dumps({"error": str(e)}), 400, {"Content-Type": "application/json"}
|
||||
except Exception as e:
|
||||
return json.dumps({"error": str(e)}), 400, {"Content-Type": "application/json"}
|
||||
|
||||
|
||||
@controller.get("/<id>")
|
||||
@with_session
|
||||
async def get_sequence(request, session, id):
|
||||
|
||||
Reference in New Issue
Block a user