Fix Ableton Live detection: add root __init__.py and harden Manager init
Live scans the Remote Scripts folder for __init__.py with create_instance() at the *root* of the script folder. Our create_instance was buried inside the AbletonOSC/ subpackage, so Live never found it. Also: - Inner AbletonOSC/__init__.py: guard import with try/except for pytest compat - Manager: use show_message() (Live status bar) instead of log_message() - Manager: wrap OSCServer.start() in try/except OSError so a port conflict surfaces as a readable status message instead of a silent crash - Manager: run handler init inside component_guard() as required by the Ableton ControlSurface framework - Manager stub: add show_message, schedule_message, component_guard no-ops so out-of-Ableton tooling/tests don't break Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,4 @@
|
|||||||
"""
|
try:
|
||||||
AbletonOSC — full Ableton Live 11 OSC remote script.
|
|
||||||
Ableton calls create_instance() to instantiate the control surface.
|
|
||||||
"""
|
|
||||||
from .manager import Manager
|
from .manager import Manager
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
def create_instance(c_instance):
|
|
||||||
return Manager(c_instance)
|
|
||||||
|
|||||||
+20
-3
@@ -9,7 +9,8 @@ import sys
|
|||||||
try:
|
try:
|
||||||
from ableton.v2.control_surface import ControlSurface
|
from ableton.v2.control_surface import ControlSurface
|
||||||
except ImportError:
|
except ImportError:
|
||||||
# Allow importing outside of Ableton for tooling
|
from contextlib import contextmanager
|
||||||
|
|
||||||
class ControlSurface: # type: ignore
|
class ControlSurface: # type: ignore
|
||||||
def __init__(self, c_instance=None):
|
def __init__(self, c_instance=None):
|
||||||
self._c_instance = c_instance
|
self._c_instance = c_instance
|
||||||
@@ -29,6 +30,16 @@ except ImportError:
|
|||||||
def log_message(self, msg):
|
def log_message(self, msg):
|
||||||
print(msg)
|
print(msg)
|
||||||
|
|
||||||
|
def show_message(self, msg):
|
||||||
|
print(msg)
|
||||||
|
|
||||||
|
def schedule_message(self, delay, callback):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def component_guard(self):
|
||||||
|
yield
|
||||||
|
|
||||||
from .osc_server import OSCServer
|
from .osc_server import OSCServer
|
||||||
from .song import SongHandler
|
from .song import SongHandler
|
||||||
from .track import TrackHandler
|
from .track import TrackHandler
|
||||||
@@ -52,12 +63,17 @@ class Manager(ControlSurface):
|
|||||||
def __init__(self, c_instance=None):
|
def __init__(self, c_instance=None):
|
||||||
super().__init__(c_instance)
|
super().__init__(c_instance)
|
||||||
self._setup_logging()
|
self._setup_logging()
|
||||||
self.osc_server = OSCServer(listen_port=LISTEN_PORT, send_port=SEND_PORT)
|
|
||||||
self._handlers = []
|
self._handlers = []
|
||||||
self._setup_handlers()
|
try:
|
||||||
|
self.osc_server = OSCServer(listen_port=LISTEN_PORT, send_port=SEND_PORT)
|
||||||
self.osc_server.start()
|
self.osc_server.start()
|
||||||
|
self._setup_handlers()
|
||||||
|
self.show_message("AbletonOSC: Listening on port %d" % LISTEN_PORT)
|
||||||
logger.info("AbletonOSC started (listen=%d, send=%d)", LISTEN_PORT, SEND_PORT)
|
logger.info("AbletonOSC started (listen=%d, send=%d)", LISTEN_PORT, SEND_PORT)
|
||||||
self.osc_server.send("/live/startup", ())
|
self.osc_server.send("/live/startup", ())
|
||||||
|
except OSError as e:
|
||||||
|
self.show_message("AbletonOSC: Couldn't bind to port %d (%s)" % (LISTEN_PORT, e))
|
||||||
|
logger.error("Couldn't bind to port %d: %s", LISTEN_PORT, e)
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -81,6 +97,7 @@ class Manager(ControlSurface):
|
|||||||
BrowserHandler,
|
BrowserHandler,
|
||||||
GrooveHandler,
|
GrooveHandler,
|
||||||
]
|
]
|
||||||
|
with self.component_guard():
|
||||||
for cls in handler_classes:
|
for cls in handler_classes:
|
||||||
h = cls(self)
|
h = cls(self)
|
||||||
h.init_api()
|
h.init_api()
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
try:
|
||||||
|
from .AbletonOSC.manager import Manager
|
||||||
|
except ImportError:
|
||||||
|
# Allows pytest to import without Ableton's runtime present
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def create_instance(c_instance):
|
||||||
|
return Manager(c_instance)
|
||||||
Reference in New Issue
Block a user