From 4d1651d03895cbb22e3defacac439ba13b7111e2 Mon Sep 17 00:00:00 2001 From: Daniel Mach Date: Thu, 4 Jul 2024 14:17:09 +0200 Subject: [PATCH 1/2] Fix colorize() to avoid wrapping empty string into color escape sequences --- osc/output/tty.py | 3 +++ tests/test_output.py | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/osc/output/tty.py b/osc/output/tty.py index c99a6e35..acb104f6 100644 --- a/osc/output/tty.py +++ b/osc/output/tty.py @@ -44,6 +44,9 @@ def colorize(text, color): if not color: return text + if not text: + return text + result = "" for i in color.split(","): result += ESCAPE_CODES[i] diff --git a/tests/test_output.py b/tests/test_output.py index 9800a499..cabe2963 100644 --- a/tests/test_output.py +++ b/tests/test_output.py @@ -74,6 +74,13 @@ Key : Value """.strip() self.assertEqual(str(t), expected) + def test_empty_value_no_color(self): + t = KeyValueTable() + t.add("Key", "", color="bold") + + expected = "Key : " + self.assertEqual(str(t), expected) + class TestPrintMsg(unittest.TestCase): def setUp(self): From 52f076636d09c25787c947ed14544ead9b4a113c Mon Sep 17 00:00:00 2001 From: Daniel Mach Date: Thu, 4 Jul 2024 14:21:48 +0200 Subject: [PATCH 2/2] Make most of the fields in KeyinfoPubkey and KeyinfoSslcert models optional The presence of the fields seems to be random and the only truly required field is the actual public key/cert. Other fields are only for the information. --- osc/obs_api/keyinfo_pubkey.py | 16 ++++++++----- osc/obs_api/keyinfo_sslcert.py | 20 +++++++++++----- tests/test_keyinfo.py | 43 ++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 12 deletions(-) create mode 100644 tests/test_keyinfo.py diff --git a/osc/obs_api/keyinfo_pubkey.py b/osc/obs_api/keyinfo_pubkey.py index a3c99515..6c516de7 100644 --- a/osc/obs_api/keyinfo_pubkey.py +++ b/osc/obs_api/keyinfo_pubkey.py @@ -4,27 +4,27 @@ from ..util.models import * # pylint: disable=wildcard-import,unused-wildcard-i class KeyinfoPubkey(XmlModel): XML_TAG = "pubkey" - keyid: str = Field( + keyid: Optional[str] = Field( xml_attribute=True, ) - userid: str = Field( + userid: Optional[str] = Field( xml_attribute=True, ) - algo: str = Field( + algo: Optional[str] = Field( xml_attribute=True, ) - keysize: str = Field( + keysize: Optional[str] = Field( xml_attribute=True, ) - expires: int = Field( + expires: Optional[int] = Field( xml_attribute=True, ) - fingerprint: str = Field( + fingerprint: Optional[str] = Field( xml_attribute=True, ) @@ -34,6 +34,10 @@ class KeyinfoPubkey(XmlModel): def get_expires_str(self) -> str: import datetime + + if self.expires is None: + return "" + return datetime.datetime.fromtimestamp(self.expires).strftime("%Y-%m-%d %H:%M:%S") def to_human_readable_string(self) -> str: diff --git a/osc/obs_api/keyinfo_sslcert.py b/osc/obs_api/keyinfo_sslcert.py index cfbf2fba..4119001b 100644 --- a/osc/obs_api/keyinfo_sslcert.py +++ b/osc/obs_api/keyinfo_sslcert.py @@ -8,7 +8,7 @@ class KeyinfoSslcert(XmlModel): xml_attribute=True, ) - serial: str = Field( + serial: Optional[str] = Field( xml_attribute=True, ) @@ -16,23 +16,23 @@ class KeyinfoSslcert(XmlModel): xml_attribute=True, ) - subject: str = Field( + subject: Optional[str] = Field( xml_attribute=True, ) - algo: str = Field( + algo: Optional[str] = Field( xml_attribute=True, ) - keysize: str = Field( + keysize: Optional[str] = Field( xml_attribute=True, ) - begins: int = Field( + begins: Optional[int] = Field( xml_attribute=True, ) - expires: int = Field( + expires: Optional[int] = Field( xml_attribute=True, ) @@ -46,10 +46,18 @@ class KeyinfoSslcert(XmlModel): def get_begins_str(self) -> str: import datetime + + if self.begins is None: + return "" + return datetime.datetime.fromtimestamp(self.begins).strftime("%Y-%m-%d %H:%M:%S") def get_expires_str(self) -> str: import datetime + + if self.expires is None: + return "" + return datetime.datetime.fromtimestamp(self.expires).strftime("%Y-%m-%d %H:%M:%S") def to_human_readable_string(self) -> str: diff --git a/tests/test_keyinfo.py b/tests/test_keyinfo.py new file mode 100644 index 00000000..9acff8dd --- /dev/null +++ b/tests/test_keyinfo.py @@ -0,0 +1,43 @@ +import unittest + +from osc import obs_api + + +class TestKeyinfo(unittest.TestCase): + def test_empty_pubkey(self): + ki = obs_api.Keyinfo() + ki.pubkey_list = [{"value": ""}] + + expected = """ +Type : GPG public key +User ID : +Algorithm : +Key size : +Expires : +Fingerprint : +""".strip() + actual = ki.pubkey_list[0].to_human_readable_string() + self.assertEqual(expected, actual) + + def test_empty_sslcert(self): + ki = obs_api.Keyinfo() + ki.sslcert_list = [{"value": ""}] + + expected = """ +Type : SSL certificate +Subject : +Key ID : +Serial : +Issuer : +Algorithm : +Key size : +Begins : +Expires : +Fingerprint : +""".strip() + actual = ki.sslcert_list[0].to_human_readable_string() + self.assertEqual(expected, actual) + + +if __name__ == "__main__": + unittest.main()