From 6073e157b79cf87b79ff36dec04fdd3ca4d111f0 Mon Sep 17 00:00:00 2001 From: Luc Busquin <133058544+Cybis320@users.noreply.github.com> Date: Thu, 20 Aug 2026 15:17:02 -0400 Subject: [PATCH 1/2] ConfigReader: normalize the case of enum-like capture options --- RMS/ConfigReader.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/RMS/ConfigReader.py b/RMS/ConfigReader.py index 47512c84b..b15a5aaf1 100644 --- a/RMS/ConfigReader.py +++ b/RMS/ConfigReader.py @@ -1107,16 +1107,16 @@ def parseCapture(config, parser): pass if parser.has_option(section, "protocol"): - config.protocol = parser.get(section, "protocol") + config.protocol = parser.get(section, "protocol").strip().lower() if parser.has_option(section, "udp_buffer_size"): config.udp_buffer_size = parser.getint(section, "udp_buffer_size") if parser.has_option(section, "media_backend"): - config.media_backend = parser.get(section, "media_backend") + config.media_backend = parser.get(section, "media_backend").strip().lower() if parser.has_option(section, "gst_colorspace"): - config.gst_colorspace = parser.get(section, "gst_colorspace") + config.gst_colorspace = parser.get(section, "gst_colorspace").strip().upper() if parser.has_option(section, "gst_decoder"): config.gst_decoder = parser.get(section, "gst_decoder") @@ -1225,7 +1225,7 @@ def parseCapture(config, parser): config.save_frames = save_requested if parser.has_option(section, "frame_file_type"): - config.frame_file_type = parser.get(section, "frame_file_type") + config.frame_file_type = parser.get(section, "frame_file_type").strip().lower() # Load the JPEG quality if parser.has_option(section, "jpgs_quality"): @@ -1252,7 +1252,7 @@ def parseCapture(config, parser): # Set whether to delete, archive, or leave saved frames after making timelapse ('delete', 'tar', 'none') if parser.has_option(section, "frame_cleanup"): - config.frame_cleanup = parser.get(section, "frame_cleanup") + config.frame_cleanup = parser.get(section, "frame_cleanup").strip().lower() # Enable/disable showing a slideshow of last night's meteor detections on the screen during the day if parser.has_option(section, "slideshow_enable"): From bcc412d77ed3524541958d19efb3d98d603ab478 Mon Sep 17 00:00:00 2001 From: Denis Vida Date: Mon, 24 Aug 2026 13:50:59 -0400 Subject: [PATCH 2/2] ConfigReader: preserve GStreamer format casing --- RMS/ConfigReader.py | 7 +++++- Tests/test_ConfigReader.py | 47 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 Tests/test_ConfigReader.py diff --git a/RMS/ConfigReader.py b/RMS/ConfigReader.py index b15a5aaf1..c5c923199 100644 --- a/RMS/ConfigReader.py +++ b/RMS/ConfigReader.py @@ -1116,7 +1116,12 @@ def parseCapture(config, parser): config.media_backend = parser.get(section, "media_backend").strip().lower() if parser.has_option(section, "gst_colorspace"): - config.gst_colorspace = parser.get(section, "gst_colorspace").strip().upper() + gst_colorspace = parser.get(section, "gst_colorspace").strip() + + # Normalize the formats explicitly supported by RMS, while preserving the case of other + # GStreamer formats (e.g. RGBx and v210) whose canonical names are case-sensitive. + supported_gst_colorspaces = {'bgr': 'BGR', 'gray8': 'GRAY8'} + config.gst_colorspace = supported_gst_colorspaces.get(gst_colorspace.lower(), gst_colorspace) if parser.has_option(section, "gst_decoder"): config.gst_decoder = parser.get(section, "gst_decoder") diff --git a/Tests/test_ConfigReader.py b/Tests/test_ConfigReader.py new file mode 100644 index 000000000..62c3aafe5 --- /dev/null +++ b/Tests/test_ConfigReader.py @@ -0,0 +1,47 @@ +"""Focused tests for capture option parsing.""" + +import pytest + +from RMS import ConfigReader as cr + + +def _parseCaptureOptions(monkeypatch, tmp_path, options): + """Parse a minimal Capture section with the supplied options.""" + parser = cr.RawConfigParser() + parser.add_section('Capture') + parser.set('Capture', 'save_frames', 'false') + + for option, value in options.items(): + parser.set('Capture', option, value) + + config = cr.Config() + config.config_file_path = str(tmp_path) + monkeypatch.setattr(cr, 'isFfmpegWorking', lambda: False) + cr.parseCapture(config, parser) + + return config + + +def testCaptureEnumOptionsAreNormalized(monkeypatch, tmp_path): + config = _parseCaptureOptions(monkeypatch, tmp_path, { + 'protocol': ' UDP ', + 'media_backend': ' GST ', + 'gst_colorspace': ' gray8 ', + 'frame_file_type': ' PNG ', + 'frame_cleanup': ' Delete ', + }) + + assert config.protocol == 'udp' + assert config.media_backend == 'gst' + assert config.gst_colorspace == 'GRAY8' + assert config.frame_file_type == 'png' + assert config.frame_cleanup == 'delete' + + +@pytest.mark.parametrize('gst_colorspace', ['RGBx', 'xRGB', 'v210', 'r210']) +def testCapturePreservesCanonicalGstColorspaceCase(monkeypatch, tmp_path, gst_colorspace): + config = _parseCaptureOptions(monkeypatch, tmp_path, { + 'gst_colorspace': ' {} '.format(gst_colorspace), + }) + + assert config.gst_colorspace == gst_colorspace