#!/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 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 sys import path as sys_path
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}
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:
- 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
- texts += [f'{label} {items_pc.pop()}' + 'M' * int(dev['mute'])]
+ texts += [f'{label} {items_pc.pop()}' + 'M' * int(dev_info['mute'])]
return ' '.join(texts)
--- /dev/null
+'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)
#!/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.pactl import pactl, pactl_info_default_dev
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'
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)
+ 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:
- 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)
- 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 ''))