pipewire_python._utils API documentation

Edit on GitHub

# pipewire_python._utils

Here we store internal functions, don't expect to see something here in documentation html version.

View Source

      1"""
      2Here we store internal functions, don't expect
      3to see something here in documentation html version.
      4"""
      5import asyncio
      6import re
      7import subprocess
      8from typing import Dict, List
      9
     10# Loading constants Constants.py
     11from ._constants import MESSAGES_ERROR
     12
     13
     14def _print_std(
     15    stdout: bytes,
     16    stderr: bytes,
     17    # Debug
     18    verbose: bool = False,
     19):
     20    """
     21    Print terminal output if are different to None and verbose activated
     22    """
     23
     24    if stdout is not None and verbose:
     25        print(f"[_print_std][stdout][type={type(stdout)}]\n{stdout.decode()}")
     26    if stderr is not None and verbose:
     27        print(f"[_print_std][stderr][type={type(stderr)}]\n{stderr.decode()}")
     28
     29
     30def _get_dict_from_stdout(
     31    stdout: str,
     32    # Debug
     33    verbose: bool = False,
     34):
     35    """
     36    Converts shell output (str) to dictionary looking for
     37    "default" and "--" values
     38    """
     39
     40    rows = stdout.split("\n")
     41    config_dict = {}
     42    for row in rows:
     43        if "default" in row:
     44            key = "--" + row.split("--")[1].split(" ")[0]
     45            value = row.split("default ")[1].replace(")", "")
     46            config_dict[key] = value
     47    if verbose:
     48        print(config_dict)
     49    return config_dict
     50
     51
     52def _update_dict_by_dict(
     53    main_dict: Dict,
     54    secondary_dict: Dict,
     55):
     56    """
     57    Update values of one dictionary with values of another dictionary
     58    based on keys
     59    """
     60    return main_dict.update(([(key, secondary_dict[key]) for key in secondary_dict.keys()]))
     61
     62
     63def _drop_keys_with_none_values(main_dict: dict):
     64    """
     65    Drop keys with None values to parse safe dictionary config
     66    """
     67    return {k: v for k, v in main_dict.items() if v is not None}
     68
     69
     70def _generate_command_by_dict(
     71    mydict: Dict,
     72    # Debug
     73    verbose: bool = False,
     74):
     75    """
     76    Generate an array based on dictionary with keys and values
     77    """
     78    array_command = []
     79    # append to a list
     80    for key, value in mydict.items():
     81        array_command.extend([key, value])
     82    if verbose:
     83        print(array_command)
     84    # return values
     85    return array_command
     86
     87
     88def _execute_shell_command(
     89    command: List[str],
     90    timeout: int = -1,  # *default= no limit
     91    # Debug
     92    verbose: bool = False,
     93):
     94    """
     95    Execute command on terminal via subprocess
     96
     97    Args:
     98        - command (str): command line to execute. Example: 'ls -l'
     99        - timeout (int): (seconds) time to end the terminal process
    100        - verbose (bool): print variables for debug purposes
    101    Return:
    102        - stdout (str): terminal response to the command
    103        - stderr (str): terminal response to the command
    104    """
    105    # Create subprocess
    106    # NO-RESOURCE-ALLOCATING
    107    # terminal_subprocess = subprocess.Popen(
    108    #     command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT  # Example ['ls ','l']
    109    # )
    110
    111    with subprocess.Popen(
    112        command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT  # Example ['ls ','l']
    113    ) as terminal_subprocess:
    114        # Execute command depending or not in timeout
    115        try:
    116            if timeout == -1:
    117                stdout, stderr = terminal_subprocess.communicate()
    118            else:
    119                stdout, stderr = terminal_subprocess.communicate(timeout=timeout)
    120        except subprocess.TimeoutExpired:  # When script finish in time
    121            terminal_subprocess.kill()
    122            stdout, stderr = terminal_subprocess.communicate()
    123
    124        # Print terminal output
    125        _print_std(stdout, stderr, verbose=verbose)
    126
    127        # Return terminal output
    128        return stdout, stderr
    129
    130
    131async def _execute_shell_command_async(
    132    command,
    133    timeout: int = -1,
    134    # Debug
    135    verbose: bool = False,
    136):
    137    """[ASYNC] Function that execute terminal commands in asyncio way
    138
    139    Args:
    140        - command (str): command line to execute. Example: 'ls -l'
    141    Return:
    142        - stdout (str): terminal response to the command.
    143        - stderr (str): terminal response to the command.
    144    """
    145    if timeout == -1:
    146        # No timeout
    147        terminal_process_async = await asyncio.create_subprocess_shell(
    148            command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
    149        )
    150        stdout, stderr = await terminal_process_async.communicate()
    151        print(
    152            f"[_execute_shell_command_async]\
    153                [{command!r} exited with\
    154                {terminal_process_async.returncode}]"
    155        )
    156        _print_std(stdout, stderr, verbose=verbose)
    157
    158    else:
    159        raise NotImplementedError(MESSAGES_ERROR["NotImplementedError"])
    160
    161    return stdout, stderr
    162
    163
    164def _generate_dict_list_targets(
    165    longstring: str,  # string output of shell
    166    # Debug
    167    verbose: bool = False,
    168):
    169    """
    170    Function that transform long string of list targets
    171    to a `dict`
    172    """
    173
    174    regex_id = r"(\d.*):"
    175    regex_desc = r'description="([^"]*)"'
    176    regex_prio = r"prio=(-?\d.*)"
    177    regex_default_node = r"[*]\t(\d\d)"
    178    regex_alsa_node = r"(alsa_[a-zA-Z].*)"
    179
    180    results_regex_id = re.findall(regex_id, longstring)
    181    results_regex_desc = re.findall(regex_desc, longstring)
    182    results_regex_prio = re.findall(regex_prio, longstring)
    183    results_regex_default_node = re.findall(regex_default_node, longstring)
    184    results_regex_alsa_mode = re.findall(regex_alsa_node, longstring)
    185
    186    mydict = {}
    187    for idx, _ in enumerate(results_regex_id):
    188        mydict[results_regex_id[idx]] = {
    189            "description": results_regex_desc[idx],
    190            "prior": results_regex_prio[idx],
    191        }
    192    mydict["_list_nodes"] = results_regex_id
    193    mydict["_node_default"] = results_regex_default_node
    194    mydict["_alsa_node"] = results_regex_alsa_mode
    195
    196    if verbose:
    197        print(mydict)
    198
    199    return mydict
    200
    201
    202def _generate_dict_interfaces(
    203    longstring: str,  # string output of shell
    204    # Debug
    205    verbose: bool = False,
    206):
    207    """
    208    Function that transform long string of list interfaces
    209    to a `dict`
    210    """
    211
    212    mydict = {}
    213    text_in_lines = longstring.split("\n")
    214    first_level = "X"
    215
    216    for line in text_in_lines:
    217        try:
    218            is_interface = True
    219            if "id: " in line:
    220                # when interface starts
    221                regex_id = r"\tid: ([0-9]*)"
    222                results_regex_id = re.findall(regex_id, line)
    223                is_interface = False
    224
    225            if is_interface:
    226                if "*" in line[:1]:
    227                    # delete * on each line at the beginning
    228                    line = line[1:]
    229                if "\t\t" in line:
    230                    # third level data
    231                    data = line.replace("\t\t", "")
    232                    data = data.split(" = ")
    233                    third_level = str(data[0])
    234                    data_to_place = " ".join(data[1:]).replace('"', "")
    235
    236                    if "properties" not in mydict[first_level]:
    237                        mydict[first_level]["properties"] = {}
    238                    if third_level not in mydict[first_level]["properties"]:
    239                        mydict[first_level]["properties"][third_level] = {}
    240                    mydict[first_level]["properties"][third_level] = data_to_place
    241
    242                elif "\t  " in line:
    243                    # second level data: params
    244
    245                    data = line.replace("\t  ", "").split(" ")
    246                    third_level = str(data[0])
    247                    if type(mydict[first_level]["params"]) != dict:
    248                        mydict[first_level]["params"] = {}
    249                    mydict[first_level]["params"][third_level] = {
    250                        "spa": data[1],
    251                        "permissions": data[2],
    252                    }
    253
    254                elif "\t" in line:
    255                    # first level data
    256                    data = line.replace("\t", "")
    257                    data = data.split(": ")
    258                    first_level = str(results_regex_id[0])
    259                    second_level = str(data[0])
    260                    data_to_place = " ".join(data[1:]).replace('"', "")
    261
    262                    # to_dict
    263                    if first_level not in mydict:
    264                        mydict[str(first_level)] = {}
    265
    266                    mydict[first_level][second_level] = data_to_place
    267        except Exception as e:
    268            print(e)
    269
    270    if verbose:
    271        print(mydict)
    272
    273    return mydict
    274
    275
    276def _filter_by_type(
    277    dict_interfaces: dict,  # interfaecs dict
    278    type_interfaces: str,  # string with type
    279    # Debug
    280    verbose: bool = False,
    281):
    282    """
    283    Function that filters a `dict` by type of interface
    284    """
    285
    286    dict_filtered = {}
    287    for key in dict_interfaces:
    288        # Filter
    289        if type_interfaces in dict_interfaces[key]["type"]:
    290            dict_filtered[key] = dict_interfaces[key]
    291
    292    if verbose:
    293        print(dict_filtered)
    294
    295    return dict_filtered