#!/usr/bin/env python3 import argparse import time import actions import pickle class CreateFileType(argparse.FileType): def __init__(self, mode='r', bufsize=-1, encoding=None, errors=None): super().__init__(mode, bufsize, encoding, errors) self.__mode = mode self.__bufsize = bufsize self.__encoding = encoding self.__errors = errors def __call__(self, string): try: return super().__call__(string) except argparse.ArgumentTypeError as e: return open(string, 'wb' if 'b' in self.__mode else 'w', self.__bufsize, self.__encoding, self.__errors) parser = argparse.ArgumentParser(description='Pulseaudio volume manager for xmobar') parser.add_argument('output_pipe', type=argparse.FileType('w',bufsize=1)) parser.add_argument('command_pipe', type=argparse.FileType('r',bufsize=1)) parser.add_argument('--state-file', type=CreateFileType('r+b')) modules = [ actions.QuitControl(), actions.ChildReaperControl(), actions.RedshiftControl(), actions.VolumeControl(), ] [m.configure(parser.add_argument_group(m.__class__.__name__)) for m in modules] args = parser.parse_args() [m.bind_arguments(args) for m in modules] if args.state_file is not None and args.state_file.readable(): try: state = pickle.load(args.state_file) print(state) [m.load_state(state[m.__class__.__name__]) for m in modules if m.enabled and m.__class__.__name__ in state] except Exception as e: print(e) def output_pipe(fd): bars=' | '.join([str(m) for m in modules if m.visible]) fd.writelines(bars+"\n") def command_pipe(fd): command = str.rstrip(fd.readline()) if len(command) == 0: return False return any([m.respond_to(command) for m in modules if m.enabled]) try: while True: if command_pipe(args.command_pipe) or any([m.periodic() for m in modules if m.enabled]): output_pipe(args.output_pipe) else: time.sleep(1) finally: if args.state_file is not None: args.state_file.seek(0) args.state_file.truncate() state = {m.__class__.__name__: m.dump_state() for m in modules if m.enabled} pickle.dump(state, args.state_file) args.state_file.close() [m.cleanup() for m in modules if m.enabled]