From: sbkelley Date: Mon, 8 Dec 2025 05:57:58 +0000 (-0500) Subject: persistent config X-Git-Url: https://skyeroc.xyz/gitweb/?a=commitdiff_plain;h=6f5d1da0978e40d64f39a74d4e2b0e6335575d28;p=obs-ctl persistent config --- diff --git a/src/obs_ctl/app.py b/src/obs_ctl/app.py index 3d9e0ed..45f08ea 100644 --- a/src/obs_ctl/app.py +++ b/src/obs_ctl/app.py @@ -28,7 +28,7 @@ class OBSCtlApp(App): # type: ignore def compose(self): yield Header() yield Footer() - yield obs.API(const.UPDATE_INTERVAL, ws_host=const.HOST, ws_port=const.PORT, ws_password=const.PASSWORD, ws_timeout=const.TIMEOUT, id="api") + yield obs.API(const.CONFIG.update_interval, ws_host=const.CONFIG.host, ws_port=const.CONFIG.port, ws_password=const.CONFIG.password, ws_timeout=const.CONFIG.timeout, id="api") logger.debug("Composing OBSCtlApp") with ScrollableContainer(classes="scrollbox"): with VerticalGroup(classes="content"): @@ -40,7 +40,7 @@ class OBSCtlApp(App): # type: ignore def on_mount(self, message: events.Mount): - self.theme = const.THEME + self.theme = const.CONFIG.theme obsws_pane = self.get_websocket_pane() api = self.get_api() obsws_pane.host = api.ws_host @@ -173,23 +173,40 @@ class OBSCtlApp(App): # type: ignore self.get_api().set_record_path(message.value) + @on(OBSWebSocketPane.HostSubmitted) + def on_settings_block_host_submitted(self, message: OBSWebSocketPane.HostSubmitted): + const.CONFIG.host = self.get_api().ws_host = message.value + + + @on(OBSWebSocketPane.PortSubmitted) + def on_settings_block_port_submitted(self, message: OBSWebSocketPane.PortSubmitted): + const.CONFIG.port = self.get_api().ws_port = message.value + + + @on(OBSWebSocketPane.PasswordSubmitted) + def on_settings_block_password_submitted(self, message: OBSWebSocketPane.PasswordSubmitted): + const.CONFIG.password = self.get_api().ws_password = message.value + + + @on(OBSWebSocketPane.TimeoutSubmitted) + def on_settings_block_timeout_submitted(self, message: OBSWebSocketPane.TimeoutSubmitted): + const.CONFIG.timeout = self.get_api().ws_timeout = message.value + + @on(OBSCTLPane.ThemeSubmitted, "#obs_ctl_pane") def on_settings_block_obsctl_theme_changed(self, message: OBSCTLPane.ThemeSubmitted): - self.theme = message.value + const.CONFIG.theme = self.theme = message.value @on(OBSCTLPane.UpdateIntervalSubmitted, "#obs_ctl_pane") def on_settings_block_obsctl_update_interval_changed(self, message:OBSCTLPane.ThemeSubmitted): - self.get_api().interval = message.value - - - def watch_theme(self, value): - self.get_obs_ctl_pane().theme = value + const.CONFIG.update_interval = self.get_api().interval = message.value def update_monitors(self, obs_stats: obs.OBSStats): self.get_settings_pane().record_path = obs_stats.record_directory self.get_stats_display().update_text_readouts(obs_stats) + const.CONFIG.save_config() def get_api(self) -> obs.API: return typing.cast(obs.API, self.query_exactly_one("#api")) diff --git a/src/obs_ctl/const.py b/src/obs_ctl/const.py index c32ad61..71fe621 100644 --- a/src/obs_ctl/const.py +++ b/src/obs_ctl/const.py @@ -1,24 +1,12 @@ +import importlib.resources +from pathlib import Path from platformdirs import PlatformDirs from configparser import ConfigParser +from . import data # App Info APPNAME = "obs-ctl" APPAUTHOR = "skyebee" VERSION = "0.0.1" -# Useful classes -USERDIRS = PlatformDirs(APPNAME, APPAUTHOR, ensure_exists=True) -CONFIG = ConfigParser() -# Config-related -POSSIBLE_CONFIG: list[str] = [USERDIRS.user_config_dir] -CURRENT_CONFIG = CONFIG.read(POSSIBLE_CONFIG) -# OBS WebSocket -HOST = "localhost" -PORT = 4455 -PASSWORD = "" -TIMEOUT = 1.0 -# obs-ctl -UPDATE_INTERVAL = 1.0 -THEME = "monokai" - # internal AVAILABLE_THEMES = [ 'textual-dark', @@ -33,4 +21,63 @@ AVAILABLE_THEMES = [ 'flexoki', 'catppuccin-latte', 'solarized-light' -] \ No newline at end of file +] +USERDIRS = PlatformDirs(APPNAME, APPAUTHOR, ensure_exists=True) +PLATFORM_CONFIG = Path(USERDIRS.user_config_dir).joinpath("config.ini") + +# Config-related +class Config: + def __init__(self): + all_config_sources: list[str] = [importlib.resources.files(data).joinpath("config.ini"), PLATFORM_CONFIG] # type: ignore + self.parser = ConfigParser(allow_no_value=True, empty_lines_in_values=False) + self.parser['websocket'] = {} + self.parser['obsctl'] = {} + self.config_sources = self.parser.read(all_config_sources) + + @property + def host(self) -> str: + return self.parser['websocket']['host'] + @host.setter + def host(self, value): + self.parser['websocket']['host'] = value + + @property + def port(self) -> int: + return self.parser['websocket'].getint('port') # type: ignore + @port.setter + def port(self, value): + self.parser['websocket']['port'] = value + + @property + def password(self) -> str: + return self.parser['websocket']['password'] + @password.setter + def password(self, value): + self.parser['websocket']['password'] = value + + @property + def timeout(self) -> float: + return self.parser['websocket'].getfloat('timeout') # type: ignore + @timeout.setter + def timeout(self, value): + self.parser['websocket']['timeout'] = value + + @property + def update_interval(self) -> float: + return self.parser['obsctl'].getfloat('UpdateInterval') # type: ignore + @update_interval.setter + def update_interval(self, value): + self.parser['obsctl']['UpdateInterval'] = value + + @property + def theme(self) -> str: + return self.parser['obsctl']['theme'] + @theme.setter + def theme(self, value): + self.parser['obsctl']['theme'] = value + + def save_config(self): + with open(PLATFORM_CONFIG, 'w') as fp: + self.parser.write(fp) + +CONFIG = Config() \ No newline at end of file diff --git a/src/obs_ctl/data/config.ini b/src/obs_ctl/data/config.ini new file mode 100644 index 0000000..5cc511a --- /dev/null +++ b/src/obs_ctl/data/config.ini @@ -0,0 +1,7 @@ +[DEFAULT] +Host = localhost +Port = 4455 +Password = +Timeout = 1.0 +UpdateInterval = 1.0 +Theme = monokai \ No newline at end of file diff --git a/src/obs_ctl/interface/molecule/settings_block/settings_block.py b/src/obs_ctl/interface/molecule/settings_block/settings_block.py index 523fe3b..9dad39a 100644 --- a/src/obs_ctl/interface/molecule/settings_block/settings_block.py +++ b/src/obs_ctl/interface/molecule/settings_block/settings_block.py @@ -14,10 +14,10 @@ OBSSettingsPane = pane.make_pane( OBSWebSocketPane = pane.make_pane( "OBSWebSocketPane", - pane.make_pane_widget("host", pane.SettingsWidget.STRING, const.HOST, compact=True), - pane.make_pane_widget("port", pane.SettingsWidget.INT, const.PORT, compact=True), - pane.make_pane_widget("password", pane.SettingsWidget.STRING, const.PASSWORD, compact=True), - pane.make_pane_widget("timeout", pane.SettingsWidget.FLOAT, const.TIMEOUT, compact=True), + pane.make_pane_widget("host", pane.SettingsWidget.STRING, const.CONFIG.host, compact=True), + pane.make_pane_widget("port", pane.SettingsWidget.INT, const.CONFIG.port, compact=True), + pane.make_pane_widget("password", pane.SettingsWidget.STRING, const.CONFIG.password, compact=True), + pane.make_pane_widget("timeout", pane.SettingsWidget.FLOAT, const.CONFIG.timeout, compact=True), ) OBSCTLPane = pane.make_pane( @@ -25,14 +25,14 @@ OBSCTLPane = pane.make_pane( pane.make_pane_widget( "theme", pane.SettingsWidget.LIST, - const.THEME, + const.CONFIG.theme, zip(const.AVAILABLE_THEMES, const.AVAILABLE_THEMES), allow_blank=False, compact=True), pane.make_pane_widget( "update_interval", pane.SettingsWidget.FLOAT, - const.UPDATE_INTERVAL, + const.CONFIG.update_interval, compact=True, ) )