home · contact · privacy
Share code between .local/bin/vol and .config/sway/status.py. master
authorPlom Heller <plom@plomlompom.com>
Fri, 18 Sep 2026 17:44:20 +0000 (19:44 +0200)
committerPlom Heller <plom@plomlompom.com>
Fri, 18 Sep 2026 17:44:20 +0000 (19:44 +0200)
home/user/.config/sway/status.py
home/user/.local/bin/lib/pactl.py [new file with mode: 0644]
home/user/.local/bin/vol

index 1fdee79b32f4e15c01cb758bab3020eb567477d6..2e390e4b1e826ca27c62ea6bd17d60609f8a4425 100755 (executable)
@@ -1,12 +1,15 @@
 #!/usr/bin/env python3
 'Sway bar status line generator.'
 #!/usr/bin/env python3
 'Sway bar status line generator.'
-from json import dumps as json_dumps, loads as json_loads
 from datetime import datetime
 from datetime import datetime
+from json import dumps as json_dumps
 from pathlib import Path
 from re import compile as re_compile
 from subprocess import run as subprocess_run
 from pathlib import Path
 from re import compile as re_compile
 from subprocess import run as subprocess_run
+from sys import path as sys_path
 from time import sleep
 from time import sleep
-from typing import Any
+sys_path.append(
+        str(Path(__file__).resolve().parents[2] / '.local' / 'bin' / 'lib'))
+from pactl import pactl_info_default_dev
 
 METADATA = {'version': 1}
 
 
 METADATA = {'version': 1}
 
@@ -37,21 +40,13 @@ def int_at_path(
 def info_audio(
         ) -> str:
     "Produce audio devices' volume, muteness."
 def info_audio(
         ) -> str:
     "Produce audio devices' volume, muteness."
-    def pactl_json(
-            *args: str
-            ) -> Any:
-        return json_loads(subprocess_run(
-            ('pactl', '-f', 'json', *args),
-            check=True, capture_output=True, text=True
-            ).stdout)
-    defaults = pactl_json('info')
     texts = []
     for dev_type, label in AUDIO_DEVS_LABELS:
     texts = []
     for dev_type, label in AUDIO_DEVS_LABELS:
-        dev = next(dev for dev in pactl_json('list', f'{dev_type}s')
-                   if dev['name'] == defaults[f'default_{dev_type}_name'])
-        items_pc = {item['value_percent'] for item in dev['volume'].values()}
+        dev_info = pactl_info_default_dev(dev_type)
+        items_pc = {item['value_percent']
+                    for item in dev_info['volume'].values()}
         assert len(items_pc) == 1
         assert len(items_pc) == 1
-        texts += [f'{label} {items_pc.pop()}' + 'M' * int(dev['mute'])]
+        texts += [f'{label} {items_pc.pop()}' + 'M' * int(dev_info['mute'])]
     return ' '.join(texts)
 
 
     return ' '.join(texts)
 
 
diff --git a/home/user/.local/bin/lib/pactl.py b/home/user/.local/bin/lib/pactl.py
new file mode 100644 (file)
index 0000000..a1e2341
--- /dev/null
@@ -0,0 +1,26 @@
+'pactl wrappers.'
+from json import loads as json_loads
+from subprocess import CompletedProcess, run as subprocess_run
+from typing import Any
+
+
+def pactl(
+        *args,
+        **kwargs
+        ) -> CompletedProcess:
+    'Run pactl command via subprocess_run.'
+    return subprocess_run(('pactl', *args), check=True, **kwargs)
+
+
+def pactl_info_default_dev(
+        device_type: str
+        ) -> dict[str, Any]:
+    "Get pactl 'list' info on device_type's ('sink'/'source') default dev."
+    def pactl_json(
+            *args
+            ) -> Any:
+        return json_loads(
+            pactl('-f', 'json', *args, capture_output=True, text=True).stdout)
+    default_name = pactl_json('info')[f'default_{device_type}_name']
+    return next(dev for dev in pactl_json('list', f'{device_type}s')
+                if dev['name'] == default_name)
index a1f70b3a225201d2c2eb9197941a5781791adbed..804adc1767314a89dc4a7449c9ce144612b4f1f4 100755 (executable)
@@ -1,13 +1,13 @@
 #!/usr/bin/env python3
 'Wrapper for manipulating audio device muteness and volume.'
 #!/usr/bin/env python3
 'Wrapper for manipulating audio device muteness and volume.'
-from subprocess import CompletedProcess, run as subprocess_run
 from lib.argparsing import ArgParser
 from lib.argparsing import ArgParser
+from lib.pactl import pactl, pactl_info_default_dev
 
 APP_DESC = 'Set audio device volume, muteness.'
 
 VOL_AT_100 = 65536
 
 APP_DESC = 'Set audio device volume, muteness.'
 
 VOL_AT_100 = 65536
-DEVICES = (('sink', 'speaker', '@DEFAULT_SINK@'),
-           ('source', 'microphone', '@DEFAULT_SOURCE@'))
+DEVICES = (('sink', 'speaker'),
+           ('source', 'microphone'))
 
 PERCENTAGE_MAX = 150
 ARG_NAME = 'volume'
 
 PERCENTAGE_MAX = 150
 ARG_NAME = 'volume'
@@ -19,33 +19,24 @@ if __name__ == '__main__':
     parser.add_arg('--mic',
                    action='store_true',
                    help='manipulate microphone rather than speaker')
     parser.add_arg('--mic',
                    action='store_true',
                    help='manipulate microphone rather than speaker')
-    dev_type, dev_name, dev_target = DEVICES[int(parser.args.mic)]
     target_percentage = getattr(parser.args, ARG_NAME)
     target_percentage = getattr(parser.args, ARG_NAME)
+    dev_type, dev_name = DEVICES[int(parser.args.mic)]
+    dev_info = pactl_info_default_dev(dev_type)
+    dev_idx = dev_info['index']
+    was_mute = dev_info['mute']
 
 
-    def pactl(
-            verb: str,
-            target: str,
-            bonus_arg='',
-            **run_kwargs
-            ) -> CompletedProcess:
-        'Run pactl command via subprocess_run.'
-        return subprocess_run(
-                ['pactl', f'{verb}-{dev_type}-{target}', dev_target
-                 ] + ([bonus_arg] if bonus_arg else []),
-                check=True,
-                **run_kwargs)
+    def pactl_set(
+            target_attr: str,
+            target_value: int,
+            ) -> None:
+        'Run "pactl set-{dev_type}-{target-attr} {dev_idx} {target_value}".'
+        pactl(f'set-{dev_type}-{target_attr}', str(dev_idx), str(target_value))
 
 
-    toks = pactl('get', 'mute', capture_output=True, text=True
-                 ).stdout.strip().split()
-    assert (len(toks) == 2
-            and toks[0] == 'Mute:'
-            and toks[1] in {'yes', 'no'}), toks
-    was_mute = toks[1] == 'yes'
     if target_percentage is None:
     if target_percentage is None:
-        pactl('set', 'mute', str(int(not was_mute)))
-        print(f'{dev_name} muteness toggled {"off" if was_mute else "on"}.')
+        pactl_set('mute', int(not was_mute))
+        print(f'{dev_name} muteness toggled {"off" if was_mute else "on"}')
     else:
         target_abs = int((target_percentage / 100) * VOL_AT_100)
     else:
         target_abs = int((target_percentage / 100) * VOL_AT_100)
-        pactl('set', 'volume', str(target_abs))
+        pactl_set('volume', target_abs)
         print(f'{dev_name} volume set to {target_percentage}% ({target_abs})'
               + (' (muted)' if was_mute else ''))
         print(f'{dev_name} volume set to {target_percentage}% ({target_abs})'
               + (' (muted)' if was_mute else ''))