aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorAdam Janovsky2025-01-27 16:31:36 +0100
committerJ08nY2025-02-01 22:57:40 +0100
commit92f7e3e2c7bc6ed32bef2fe02a59ef4c6225c6c7 (patch)
tree5c6048b16995ff0c452cbcc145a6f79e073cfa62 /src
parentbcbb31e609c1f03f8b66b9e0bc0c27ce9cd7e562 (diff)
downloadsec-certs-92f7e3e2c7bc6ed32bef2fe02a59ef4c6225c6c7.tar.gz
sec-certs-92f7e3e2c7bc6ed32bef2fe02a59ef4c6225c6c7.tar.zst
sec-certs-92f7e3e2c7bc6ed32bef2fe02a59ef4c6225c6c7.zip
process PP maintenances
Diffstat (limited to 'src')
-rw-r--r--src/sec_certs/sample/protection_profile.py13
-rw-r--r--src/sec_certs/utils/cc_html_parsing.py38
2 files changed, 47 insertions, 4 deletions
diff --git a/src/sec_certs/sample/protection_profile.py b/src/sec_certs/sample/protection_profile.py
index 079c9319..9f499451 100644
--- a/src/sec_certs/sample/protection_profile.py
+++ b/src/sec_certs/sample/protection_profile.py
@@ -19,7 +19,7 @@ from sec_certs.sample.certificate import Heuristics as BaseHeuristics
from sec_certs.sample.certificate import PdfData as BasePdfData
from sec_certs.sample.document_state import DocumentState
from sec_certs.serialization.json import ComplexSerializableType
-from sec_certs.utils import helpers, sanitization
+from sec_certs.utils import cc_html_parsing, helpers, sanitization
class ProtectionProfile(
@@ -55,7 +55,7 @@ class ProtectionProfile(
report_link: str | None
pp_link: str | None
scheme: str | None
- maintenances: list[tuple[date, str, str]]
+ maintenances: list[tuple[Any]]
@property
def eal(self) -> str | None:
@@ -88,7 +88,12 @@ class ProtectionProfile(
if not sanitization.sanitize_cc_link(pp_link):
raise ValueError(f"pp_link for PP {pp_name} is empty, cannot create PP record")
- # TODO: Parse maintenance div here. See CC parsing.
+ mu_div = cc_html_parsing.html_row_get_maintenance_div(row)
+ maintenance_updates = cc_html_parsing.parse_maintenance_div(mu_div) if mu_div else []
+ if maintenance_updates:
+ # Drop ST links, not filled in for PPs
+ maintenance_updates = [x[:3] for x in maintenance_updates]
+
return cls(
category,
status,
@@ -101,7 +106,7 @@ class ProtectionProfile(
cls._html_row_get_link(cells[-1]),
pp_link,
cls._html_row_get_scheme(cells[-2]),
- [],
+ maintenance_updates,
)
@classmethod
diff --git a/src/sec_certs/utils/cc_html_parsing.py b/src/sec_certs/utils/cc_html_parsing.py
new file mode 100644
index 00000000..956353bf
--- /dev/null
+++ b/src/sec_certs/utils/cc_html_parsing.py
@@ -0,0 +1,38 @@
+import logging
+from datetime import datetime
+from typing import Any
+
+from bs4 import Tag
+
+from sec_certs import constants
+
+logger = logging.getLogger(__name__)
+
+
+def html_row_get_maintenance_div(cell: Tag) -> Tag | None:
+ divs = cell.find_all("div")
+ for d in divs:
+ if d.find("div") and d.stripped_strings and list(d.stripped_strings)[0] == "Maintenance Report(s)":
+ return d
+ return None
+
+
+def parse_maintenance_div(main_div: Tag) -> list[tuple[Any, ...]]:
+ possible_updates = list(main_div.find_all("li"))
+ maintenance_updates = set()
+ for u in possible_updates:
+ text = list(u.stripped_strings)[0]
+ main_date = datetime.strptime(text.split(" ")[0], "%Y-%m-%d").date() if text else None
+ main_title = text.split("– ")[1]
+ main_report_link = None
+ main_st_link = None
+ links = u.find_all("a")
+ for link in links:
+ if link.get("title").startswith("Maintenance Report:"):
+ main_report_link = constants.CC_PORTAL_BASE_URL + link.get("href")
+ elif link.get("title").startswith("Maintenance ST"):
+ main_st_link = constants.CC_PORTAL_BASE_URL + link.get("href")
+ else:
+ logger.error("Unknown link in Maintenance part!")
+ maintenance_updates.add((main_date, main_title, main_report_link, main_st_link))
+ return list(maintenance_updates)