]> skyeroc.xyz Git - obs-ctl/commitdiff
persistent config
authorsbkelley <sb24kelley@gmail.com>
Mon, 8 Dec 2025 05:57:58 +0000 (00:57 -0500)
committersbkelley <sb24kelley@gmail.com>
Mon, 8 Dec 2025 05:57:58 +0000 (00:57 -0500)
src/obs_ctl/app.py
src/obs_ctl/const.py
src/obs_ctl/data/config.ini [new file with mode: 0644]
src/obs_ctl/interface/molecule/settings_block/settings_block.py

index 3d9e0ed7984698cfc48fbfe01d0805c6bbfb2a9e..45f08eab130f0c752c29c63febcfd171323945aa 100644 (file)
@@ -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"))
index c32ad6148e5238de0e7533bd68e35fce57a3028d..71fe6219f3f8c6de6c7002470c4f35230e7ba3e7 100644 (file)
@@ -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 (file)
index 0000000..5cc511a
--- /dev/null
@@ -0,0 +1,7 @@
+[DEFAULT]
+Host = localhost
+Port = 4455
+Password = 
+Timeout = 1.0
+UpdateInterval = 1.0
+Theme = monokai
\ No newline at end of file
index 523fe3b143eabf0dbf0c273e1ba4bbcfcb7413b1..9dad39a677f4d50a0791d0837b5223d6024cc652 100644 (file)
@@ -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,
     )
 )