From 2e1916eeaa650972c425e2e0e9a90fe485e060fb Mon Sep 17 00:00:00 2001 From: onyx-and-iris Date: Sun, 29 Oct 2023 09:20:56 +0000 Subject: [PATCH] moves timeout login into decorator function patch bump --- pyproject.toml | 2 +- voicemeeterlib/remote.py | 21 ++------------------- voicemeeterlib/util.py | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d08e31f..6bf6600 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "voicemeeter-api" -version = "2.5.1" +version = "2.5.2" description = "A Python wrapper for the Voiceemeter API" authors = ["onyx-and-iris "] license = "MIT" diff --git a/voicemeeterlib/remote.py b/voicemeeterlib/remote.py index 18f883a..498b2fb 100644 --- a/voicemeeterlib/remote.py +++ b/voicemeeterlib/remote.py @@ -14,7 +14,7 @@ from .kinds import KindId from .misc import Midi, VmGui from .subject import Subject from .updater import Producer, Updater -from .util import deep_merge, grouper, polling, script +from .util import deep_merge, grouper, polling, script, timeout logger = logging.getLogger(__name__) @@ -67,6 +67,7 @@ class Remote(CBindings): def stopped(self): return self.stop_event is None or self.stop_event.is_set() + @timeout def login(self) -> None: """Login to the API, initialize dirty parameters""" self.gui.launched = self.call(self.bind_login, ok=(0, 1)) == 0 @@ -76,24 +77,6 @@ class Remote(CBindings): ) self.run_voicemeeter(self.kind.name) - err = None - start = time.time() - while time.time() < start + self.timeout: - try: - time.sleep(0.1) # ensure at least 0.1 delay before clearing dirty - self.logger.info( - f"{type(self).__name__}: Successfully logged into {self} version {self.version}" - ) - self.logger.debug(f"login time: {round(time.time() - start, 2)}") - err = None - break - except CAPIError as e: - err = e - continue - if err: - raise VMError("Timeout logging into the api") - self.clear_dirty() - def run_voicemeeter(self, kind_id: str) -> None: if kind_id not in (kind.name.lower() for kind in KindId): raise VMError(f"Unexpected Voicemeeter type: '{kind_id}'") diff --git a/voicemeeterlib/util.py b/voicemeeterlib/util.py index a164b33..e90f3e5 100644 --- a/voicemeeterlib/util.py +++ b/voicemeeterlib/util.py @@ -1,7 +1,41 @@ import functools +import time from itertools import zip_longest from typing import Iterator +from .error import CAPIError, VMError + + +def timeout(func): + """ + Times out the login function once time elapsed exceeds remote.timeout. + """ + + @functools.wraps(func) + def wrapper(*args, **kwargs): + remote, *_ = args + func(*args, **kwargs) + + err = None + start = time.time() + while time.time() < start + remote.timeout: + try: + time.sleep(0.1) # ensure at least 0.1 delay before clearing dirty + remote.logger.info( + f"{type(remote).__name__}: Successfully logged into {remote} version {remote.version}" + ) + remote.logger.debug(f"login time: {round(time.time() - start, 2)}") + err = None + break + except CAPIError as e: + err = e + continue + if err: + raise VMError("Timeout logging into the api") + remote.clear_dirty() + + return wrapper + def polling(func): """