From 6f42c6a476562dc323d403e5d877bae722620641 Mon Sep 17 00:00:00 2001 From: David Risch Date: Sun, 17 Jan 2021 22:49:44 +0100 Subject: [PATCH] Fix bugs in parser for cards --- scripts/audio_switcher.py | 2 +- scripts/pactl_interface/card.py | 24 ++++++++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/scripts/audio_switcher.py b/scripts/audio_switcher.py index be37371..7cb4476 100755 --- a/scripts/audio_switcher.py +++ b/scripts/audio_switcher.py @@ -224,7 +224,7 @@ def get_port(self): for card in cards: debug_output += card.name + '\n' for port in card.ports: - debug_output += ' {}\n'.format(port.product_name) + debug_output += ' {}\n'.format(port.product_name if port.product_name is not None else '-') log.w('Failed to find any port on any card matching "{}". Name of the product at every port:\n{}'.format( card_port_product_name_regex, debug_output )) diff --git a/scripts/pactl_interface/card.py b/scripts/pactl_interface/card.py index 082f2dd..d0d7ea8 100755 --- a/scripts/pactl_interface/card.py +++ b/scripts/pactl_interface/card.py @@ -25,7 +25,10 @@ def __init__(self, in_dict, card): self.profiles = [] self.card = card - key, contents = list(in_dict.items())[0] + if isinstance(in_dict, str): + key, contents = in_dict, [] + else: + key, contents = list(in_dict.items())[0] match = re.match('^(.*): ', key) self.name = match.group(1) @@ -35,7 +38,7 @@ def __init__(self, in_dict, card): for property_item in content['Properties:']: if isinstance(property_item, dict): property_item, _ = list(property_item.items())[0] - match = re.match('^device.product.name = \"(.*)$', property_item) + match = re.match('^device.product.name = \"(.*)\"$', property_item) if match is not None: self.product_name = match.group(1) else: @@ -115,6 +118,21 @@ def rescan_all_cards(): if return_code != 0: log.e('\'{}\' () failed, stderr:\n{}'.format(" ".join(arguments), stderr)) + @staticmethod + def cleanup_pactl_output(cards): + # Sometimes 'device.product.name' contains a newline which causes problems. + # This is detected by lines beginning with a space or quote. + cleaned_cards = '' + previous_line = '' + for line in cards.splitlines(): + if len(line) > 0: + if line[0] == ' ' or line[0] == '"': + previous_line += line + else: + cleaned_cards += previous_line + '\n' + previous_line = line + return cleaned_cards + @classmethod def get_all_cards(cls): arguments = ['pactl', 'list', 'cards'] @@ -122,6 +140,8 @@ def get_all_cards(cls): cards = stdout + cards = cls.cleanup_pactl_output(cards) + class Node: # https://stackoverflow.com/a/53346240/13623303 def __init__(self, indented_line):