def reconnect(): """ Reconnect to REAPER ReaScript API. This function has no effect from inside REAPER. Examples -------- Assume no REAPER instance is active. >>> import reapy DisabledDistAPIWarning: Can't reach distant API. Please start REAPER, or call reapy.config.enable_dist_api() from inside REAPER to enable distant API. warnings.warn(DisabledDistAPIWarning()) >>> p = reapy.Project() # Results in error Traceback (most recent call last): File "<string>", line 1, in <module> File "C:\\Users\\despres\\Desktop\\reaper\\scripts\\reapy\\reapy\\core\\project\\project.py", line 26, in __init__ id = RPR.EnumProjects(index, None, 0)[0] AttributeError: module 'reapy.reascript_api' has no attribute 'EnumProjects' >>> # Now start REAPER ... >>> reapy.reconnect() >>> p = reapy.Project() # No error! """ global _WEB_INTERFACE, _CLIENT if not reapy.is_inside_reaper(): try: _WEB_INTERFACE = WebInterface(reapy.config.WEB_INTERFACE_PORT) _CLIENT = Client(_WEB_INTERFACE.get_reapy_server_port()) importlib.reload(reapy.reascript_api) except DisabledDistAPIError: pass
def reconnect(): """ Reconnect to REAPER ReaScript API. Examples -------- Assume no REAPER instance is active. >>> import reapy errors.DisabledDistAPIWarning: Can't reach distant API. Please start REAPER, or call reapy.config.enable_dist_api() from inside REAPER to enable distant API. warnings.warn(errors.DisabledDistAPIWarning()) >>> p = reapy.Project() # Results in error Traceback (most recent call last): File "<string>", line 1, in <module> File "reapy\\core\\project\\project.py", line 26, in __init__ id = RPR.EnumProjects(index, None, 0)[0] AttributeError: module 'reapy.reascript_api' has no attribute 'EnumProjects' >>> # Now start REAPER ... >>> reapy.reconnect() >>> p = reapy.Project() # No error! """ if not reapy.is_inside_reaper(): host = get_selected_machine_host() if host is None: # We are outside REAPER, so this means initial import failed to # connect and we want to retry with default host (i.e. localhost) host = "localhost" try: del CLIENTS[host] except KeyError: pass connect(host)
def enable_dist_api(): """Enable distant API. .. deprecated:: 0.8.0 ``enable_dist_api`` will be removed in reapy 1.0.0. Use :func:`reapy.config.configure_reaper` that works even from outside REAPER. Create a Web interface and add the ReaScript ``reapy.reascripts.activate_reapy_server`` to the Actions list. """ msg = ("Function enable_dist_api is deprecated since 0.8.0. " "Use reapy.config.configure_reaper instead.") warnings.warn(FutureWarning(msg)) if not reapy.is_inside_reaper(): raise OutsideREAPERError create_new_web_interface(WEB_INTERFACE_PORT) reascript_path = get_activate_reapy_server_path() action_id = reapy.add_reascript(reascript_path) command_name = json.dumps(reapy.get_command_name(action_id)) section, key, value = "reapy", "activate_reapy_server", command_name reapy.set_ext_state(section, key, value, persist=True) message = ( "reapy successfully enabled!\n\nPlease restart REAPER.\n\nYou will " "then be able to import reapy from the outside.") reapy.show_message_box(message)
def main_loop() -> None: if is_stopped(): server.run() announce.run() if rpr.is_inside_reaper(): rpr.defer(main_loop) else: sleep(.03) main_loop()
def __call__(cls, *args: Stringable, sep: str = ' ') -> None: line = sep.join([str(i) for i in args]) if cls._console: if rpr.is_inside_reaper(): rpr.defer(rpr.print, line) else: rpr.print(line) if cls._print: print(line)
def disable_dist_api(): """ Disable distant API. Delete ``reapy`` Web interface, and remove the ReaScript ``reapy.reascripts.activate_reapy_server`` from the Actions list. """ if not reapy.is_inside_reaper(): raise OutsideREAPERError delete_web_interface(reapy.get_resource_path(), WEB_INTERFACE_PORT) reascript_path = get_activate_reapy_server_path() reapy.remove_reascript(reascript_path) message = ("reapy will be disabled as soon as you restart REAPER.") reapy.show_message_box(message)
def __call__(self, func, encoded_func=None): if reapy.is_inside_reaper() or _CLIENT is None: return func if isinstance(func, property): return DistProperty.from_property(func) # Check if the decorated function is from reapy module_name = func.__module__ if module_name == 'reapy' or module_name.startswith('reapy.'): @functools.wraps(func) def wrap(*args, **kwargs): f = func if encoded_func is None else encoded_func return _CLIENT.request(f, {"args": args, "kwargs": kwargs}) return wrap # Otherwise, use the context manager return super().__call__(func)
def register_machine(host): """Register a slave machine. Parameters ---------- host : str Slave machine host (e.g. ``"localhost"``). See also -------- ``reapy.connect`` """ if reapy.is_inside_reaper() and host == "localhost": msg = "A REAPER instance can not connect to istelf." raise errors.InsideREAPERError(msg) interface_port = reapy.config.WEB_INTERFACE_PORT interface = web_interface.WebInterface(interface_port, host) CLIENTS[host] = client.Client(interface.get_reapy_server_port(), host)
def enable_dist_api(): """ Enable distant API. Create a Web interface and add the ReaScript ``reapy.reascripts.activate_reapy_server`` to the Actions list. """ if not reapy.is_inside_reaper(): raise OutsideREAPERError create_new_web_interface(WEB_INTERFACE_PORT) reascript_path = get_activate_reapy_server_path() action_id = reapy.add_reascript(reascript_path) command_name = json.dumps(reapy.get_command_name(action_id)) section, key, value = "reapy", "activate_reapy_server", command_name reapy.set_ext_state(section, key, value, persist=True) message = ( "reapy successfully enabled!\n\nPlease restart REAPER.\n\nYou will " "then be able to import reapy from the outside.") reapy.show_message_box(message)
def defer(f, *args, **kwargs): """ Make REAPER call a function later. Parameters ---------- f : callable Function to be called later. args : tuple, optional Positional arguments to pass to ``f``. kwargs : dict, optional Keyword arguments to pass to ``f``. Raises ------ AssertionError When called from outside REAPER. Notes ----- The average time before a defered call is actually run is about 0.03 seconds (around 30 defered calls are allowed per second). Examples -------- Typical use case of ``defer`` is running loops that don't block REAPER GUI. The following example creates a loop that indefinitely prints integers to the REAPER console, without blocking REAPER GUI. >>> import reapy >>> def stupid_loop(i): ... reapy.print(i) ... reapy.defer(stupid_loop, i + 1) ... >>> stupid_loop(0) """ # Check we are inside REAPER message = "reapy.defer can only be called inside REAPER." assert reapy.is_inside_reaper(), message Deferrer().defer(f, args, kwargs)
def at_exit(f, *args, **kwargs): """ Make REAPER call a function after script execution. The function is also called if excution is terminated by user. Parameters ---------- f : callable Function to be called later. args : tuple, optional Positional arguments to pass to ``f``. kwargs : dict, optional Keyword arguments to pass to ``f``. Raises ------ AssertionError When called from outside REAPER. Examples -------- Typical use case of ``at_exit`` is cleaning up after a ``defer`` loop. The following example opens a file and starts a loop that indefinitely writes integers to that file. Since we want the file to be closed when the user terminates script execution, call to its ``close`` method is deferred to ``reapy.at_exit``. >>> import reapy >>> file = open("somefile.txt", "w") >>> def stupid_loop(i): ... file.write(i) ... reapy.defer(stupid_loop, i + 1) ... >>> reapy.at_exit(file.close) >>> stupid_loop(0) """ message = "reapy.at_exit can only be called inside REAPER." assert reapy.is_inside_reaper(), message Deferrer().defer(f, args, kwargs, at_exit=True)
import reapy if not reapy.is_inside_reaper(): try: from reapy_generated_api import __all__ from reapy_generated_api import * except ImportError: # Happens when ``reapy`` dist API is disabled __all__ = []
raise RuntimeError('cannot run slave') HOST = host else: HOST = rpr.get_ext_state(EXT_SECTION, ADDRESS_KEY_SLAVE) handlers = [PrintHandler, PingHandler] server = ReaperServer(HOST, PORT, handlers) announce = Announce(HOST, PORT) def main_loop() -> None: if is_stopped(): server.run() announce.run() if rpr.is_inside_reaper(): rpr.defer(main_loop) else: sleep(.03) main_loop() def at_exit() -> None: server.at_exit() log(f'starting slave on {HOST}:{PORT}') if rpr.is_inside_reaper(): rpr.at_exit(at_exit) main_loop()
def __enter__(self): if not reapy.is_inside_reaper(): _CLIENT.request("HOLD")
def __exit__(self, exc_type, exc_val, exc_tb): if not reapy.is_inside_reaper(): machines.get_selected_client().request("RELEASE") return False
def __enter__(self): if not reapy.is_inside_reaper(): machines.get_selected_client().request("HOLD")
def __exit__(self, exc_type, exc_val, exc_tb): if not reapy.is_inside_reaper(): _CLIENT.request("RELEASE") return False
def run(self, **input): if reapy.is_inside_reaper(): return super(Program, self).run(**input) else: return CLIENT.run_program(self, input)
def __exit__(self, exc_type, exc_val, exc_tb): if not reapy.is_inside_reaper(): dist_program.Program("RELEASE").run() return False
import reapy import sys if reapy.is_inside_reaper(): # Import functions without the useless starting "RPR_". import reaper_python as _RPR __all__ = [s[4:] for s in _RPR.__dict__ if s.startswith("RPR_")] for s in __all__: exec("{} = _RPR.__dict__['{}']".format(s, "RPR_" + s)) # Import SWS functions. try: import sws_python as _SWS sws_functions = set(_SWS.__dict__) - set(_RPR.__dict__) __all__ += list(sws_functions) for s in sws_functions: exec("from sws_python import {}".format(s)) except ModuleNotFoundError: # SWS is not installed pass else: from .dist_api import __all__ from .dist_api import *
def __enter__(self): if not reapy.is_inside_reaper(): dist_program.Program("HOLD").run()