mirror of
https://github.com/kellyjonbrazil/jc.git
synced 2025-08-08 22:36:48 +02:00
allow parser to deal with null input
This commit is contained in:
@@ -90,6 +90,7 @@ from typing import Dict
|
|||||||
|
|
||||||
import jc.utils
|
import jc.utils
|
||||||
from jc.utils import convert_to_int
|
from jc.utils import convert_to_int
|
||||||
|
from jc.exceptions import ParseError
|
||||||
|
|
||||||
class info():
|
class info():
|
||||||
"""Provides parser metadata (version, author, etc.)"""
|
"""Provides parser metadata (version, author, etc.)"""
|
||||||
@@ -115,6 +116,9 @@ def _process(proc_data: Dict) -> Dict:
|
|||||||
Returns:
|
Returns:
|
||||||
(dict) processed structured data adhering to the schema
|
(dict) processed structured data adhering to the schema
|
||||||
"""
|
"""
|
||||||
|
if not proc_data:
|
||||||
|
return {}
|
||||||
|
|
||||||
# Initialize the processed dictionary
|
# Initialize the processed dictionary
|
||||||
processed = {
|
processed = {
|
||||||
"control_name": proc_data.get("control_name", ""),
|
"control_name": proc_data.get("control_name", ""),
|
||||||
@@ -209,53 +213,55 @@ def parse(
|
|||||||
|
|
||||||
# starts the parsing from here
|
# starts the parsing from here
|
||||||
mapping: Dict = {}
|
mapping: Dict = {}
|
||||||
# split lines and than work on each line
|
|
||||||
lines = data.splitlines()
|
|
||||||
first_line = lines[0].strip()
|
|
||||||
|
|
||||||
# Extract the control name from the first line
|
if jc.utils.has_data(data):
|
||||||
if first_line.startswith("Simple mixer control"):
|
# split lines and than work on each line
|
||||||
control_name = first_line.split("'")[1]
|
lines = data.splitlines()
|
||||||
else:
|
first_line = lines[0].strip()
|
||||||
raise ValueError("Invalid amixer output format: missing control name.")
|
|
||||||
# map the control name
|
|
||||||
mapping["control_name"] = control_name
|
|
||||||
|
|
||||||
# Process subsequent lines for capabilities, channels, limits, and channel-specific mapping.
|
# Extract the control name from the first line
|
||||||
# gets the lines from the next line - because we already took care the first line.
|
if first_line.startswith("Simple mixer control"):
|
||||||
for line in lines[1:]:
|
control_name = first_line.split("'")[1]
|
||||||
# strip the line (maybe there are white spaces in the begin&end)
|
else:
|
||||||
line = line.strip()
|
raise ParseError("Invalid amixer output format: missing control name.")
|
||||||
|
# map the control name
|
||||||
|
mapping["control_name"] = control_name
|
||||||
|
|
||||||
if line.startswith("Capabilities:"):
|
# Process subsequent lines for capabilities, channels, limits, and channel-specific mapping.
|
||||||
mapping["capabilities"] = line.split(":")[1].strip().split()
|
# gets the lines from the next line - because we already took care the first line.
|
||||||
elif line.startswith("Playback channels:"):
|
for line in lines[1:]:
|
||||||
mapping["playback_channels"] = line.split(":")[1].strip().split(" - ")
|
# strip the line (maybe there are white spaces in the begin&end)
|
||||||
elif line.startswith("Limits:"):
|
line = line.strip()
|
||||||
limits = line.split(":")[1].strip().split(" - ")
|
|
||||||
mapping["limits"] = {
|
|
||||||
"playback_min": limits[0].split()[1],
|
|
||||||
"playback_max": limits[1]
|
|
||||||
}
|
|
||||||
elif line.startswith("Mono:") or line.startswith("Front Left:") or line.startswith("Front Right:"):
|
|
||||||
# Identify the channel name and parse its information
|
|
||||||
channel_name = line.split(":")[0].strip().lower().replace(" ", "_")
|
|
||||||
channel_info = line.split(":")[1].strip()
|
|
||||||
# Example: "Playback 255 [100%] [0.00db] [on]"
|
|
||||||
channel_data = channel_info.split(" ")
|
|
||||||
if channel_data[0] == "":
|
|
||||||
continue
|
|
||||||
playback_value = channel_data[1]
|
|
||||||
percentage = channel_data[2].strip("[]") # Extract percentage e.g., "100%"
|
|
||||||
db_value = channel_data[3].strip("[]") # Extract db value e.g., "0.00db"
|
|
||||||
status = channel_data[4].strip("[]") # Extract status e.g., "on" or "off"
|
|
||||||
|
|
||||||
# Store channel mapping in the dictionary
|
if line.startswith("Capabilities:"):
|
||||||
mapping[channel_name] = {
|
mapping["capabilities"] = line.split(":")[1].strip().split()
|
||||||
"playback_value": playback_value,
|
elif line.startswith("Playback channels:"):
|
||||||
"percentage": percentage,
|
mapping["playback_channels"] = line.split(":")[1].strip().split(" - ")
|
||||||
"db": db_value.lower(),
|
elif line.startswith("Limits:"):
|
||||||
"status": status
|
limits = line.split(":")[1].strip().split(" - ")
|
||||||
}
|
mapping["limits"] = {
|
||||||
|
"playback_min": limits[0].split()[1],
|
||||||
|
"playback_max": limits[1]
|
||||||
|
}
|
||||||
|
elif line.startswith("Mono:") or line.startswith("Front Left:") or line.startswith("Front Right:"):
|
||||||
|
# Identify the channel name and parse its information
|
||||||
|
channel_name = line.split(":")[0].strip().lower().replace(" ", "_")
|
||||||
|
channel_info = line.split(":")[1].strip()
|
||||||
|
# Example: "Playback 255 [100%] [0.00db] [on]"
|
||||||
|
channel_data = channel_info.split(" ")
|
||||||
|
if channel_data[0] == "":
|
||||||
|
continue
|
||||||
|
playback_value = channel_data[1]
|
||||||
|
percentage = channel_data[2].strip("[]") # Extract percentage e.g., "100%"
|
||||||
|
db_value = channel_data[3].strip("[]") # Extract db value e.g., "0.00db"
|
||||||
|
status = channel_data[4].strip("[]") # Extract status e.g., "on" or "off"
|
||||||
|
|
||||||
|
# Store channel mapping in the dictionary
|
||||||
|
mapping[channel_name] = {
|
||||||
|
"playback_value": playback_value,
|
||||||
|
"percentage": percentage,
|
||||||
|
"db": db_value.lower(),
|
||||||
|
"status": status
|
||||||
|
}
|
||||||
|
|
||||||
return mapping if raw else _process(mapping)
|
return mapping if raw else _process(mapping)
|
||||||
|
@@ -22,6 +22,12 @@ class AmixerTests(unittest.TestCase):
|
|||||||
self.test_files_json = [f'{file}.json' for file in self.TEST_FILES_NAME]
|
self.test_files_json = [f'{file}.json' for file in self.TEST_FILES_NAME]
|
||||||
self.test_files_processed_json = [f'{file}-processed.json' for file in self.TEST_FILES_NAME]
|
self.test_files_processed_json = [f'{file}-processed.json' for file in self.TEST_FILES_NAME]
|
||||||
|
|
||||||
|
def test_amixer_sget_nodata(self):
|
||||||
|
"""
|
||||||
|
Test 'amixer' with no data
|
||||||
|
"""
|
||||||
|
self.assertEqual(jc.parsers.amixer.parse('', quiet=True), {})
|
||||||
|
|
||||||
def test_amixer_sget(self):
|
def test_amixer_sget(self):
|
||||||
for file_out, file_json, file_processed_json in zip(self.test_files_out, self.test_files_json,
|
for file_out, file_json, file_processed_json in zip(self.test_files_out, self.test_files_json,
|
||||||
self.test_files_processed_json):
|
self.test_files_processed_json):
|
||||||
|
Reference in New Issue
Block a user