diff --git a/clairmeta/dcp_check_execution.py b/clairmeta/dcp_check_execution.py index 16c8bd9..a3c98e0 100644 --- a/clairmeta/dcp_check_execution.py +++ b/clairmeta/dcp_check_execution.py @@ -79,7 +79,7 @@ def __init__(self, func): def short_desc(self): """Returns first line of the docstring or function name.""" - docstring_lines = self.doc.split("\n") + docstring_lines = self.doc.split("\n") if self.doc else "" return docstring_lines[0].strip() if docstring_lines else self.name def is_valid(self, criticality="ERROR"): diff --git a/clairmeta/dcp_check_global.py b/clairmeta/dcp_check_global.py index 4751247..0e26412 100644 --- a/clairmeta/dcp_check_global.py +++ b/clairmeta/dcp_check_global.py @@ -7,7 +7,6 @@ from clairmeta.dcp_utils import list_cpl_assets, cpl_probe_asset from clairmeta.dcp_check import CheckerBase -from clairmeta.utils.sys import all_keys_in_dict class Checker(CheckerBase): @@ -99,25 +98,29 @@ def setup_dcp_link_ov(self): ) def check_dcp_signed(self): - """DCP with encrypted content must be digitally signed. + """Encrypted DCP must be digitally signed (XMLs include Signer and Signature). References: DCI DCSS (v1.3) 5.4.3.7 DCI DCSS (v1.3) 5.5.2.3 """ for cpl in self.dcp._list_cpl: + cpl_name = cpl["FileName"] cpl_node = cpl["Info"]["CompositionPlaylist"] + if not cpl_node["Encrypted"]: + continue + xmls = [ - pkl["Info"]["PackingList"] + (pkl["FileName"], pkl["Info"]["PackingList"]) for pkl in self.dcp._list_pkl if pkl["Info"]["PackingList"]["Id"] == cpl_node.get("PKLId") ] - xmls.append(cpl_node) + xmls.append((cpl_name, cpl_node)) - for xml in xmls: - signed = all_keys_in_dict(xml, ["Signer", "Signature"]) - if not signed and cpl_node["Encrypted"] is True: - self.error("Encrypted DCP must be signed") + for name, xml in xmls: + for field in ["Signer", "Signature"]: + if field not in xml.keys(): + self.error("Missing {} element in {}".format(field, name)) def check_link_ov_coherence(self): """Relink OV/VF sanity checks. diff --git a/clairmeta/profile.py b/clairmeta/profile.py index ed76901..054920d 100644 --- a/clairmeta/profile.py +++ b/clairmeta/profile.py @@ -17,7 +17,7 @@ # 4 levels : ERROR, WARNING, INFO and SILENT. "criticality": { "default": "ERROR", - "check_dcnc_": "WARNING", + "check_dcnc_": "INFO", "check_dcp_foreign_files": "WARNING", "check_assets_am_volindex_one": "WARNING", "check_*_empty_text_fields": "WARNING", diff --git a/clairmeta/report.py b/clairmeta/report.py index fd49977..ce79c83 100644 --- a/clairmeta/report.py +++ b/clairmeta/report.py @@ -12,7 +12,15 @@ class CheckReport(object): """Check report listing all checks executions.""" - pretty_status = { + ORDERED_STATUS = [ + "ERROR", + "WARNING", + "INFO", + "SILENT", + "BYPASS", + ] + + PRETTY_STATUS = { "ERROR": "Error(s)", "WARNING": "Warning(s)", "INFO": "Info(s)", @@ -109,20 +117,20 @@ def nested_dict(): # Ignore silenced checks status_map.pop("SILENT", None) - for status, vals in six.iteritems(status_map): + for status in self.ORDERED_STATUS: out_stack = [] - for k, v in six.iteritems(vals): + for k, v in six.iteritems(status_map[status]): out_stack += [self._dump_stack("", k, v, indent_level=0)] if out_stack: report += "{}\n{}\n".format( - self.pretty_status[status] + ":", "\n".join(out_stack) + self.PRETTY_STATUS[status] + ":", "\n".join(out_stack) ) bypassed = "\n".join( set([" . " + c.short_desc() for c in self.checks_bypassed()]) ) if bypassed: - report += "{}\n{}\n".format(self.pretty_status["BYPASS"] + ":", bypassed) + report += "{}\n{}\n".format(self.PRETTY_STATUS["BYPASS"] + ":", bypassed) return report diff --git a/tests/test_dcp_check.py b/tests/test_dcp_check.py index 129a700..789e858 100644 --- a/tests/test_dcp_check.py +++ b/tests/test_dcp_check.py @@ -181,7 +181,8 @@ def test_report_checks(self): self.report.errors_by_criticality("ERROR") self.assertEqual(3, len(self.report.checks_failed())) self.assertEqual(1, len(self.report.errors_by_criticality("ERROR"))) - self.assertEqual(2, len(self.report.errors_by_criticality("WARNING"))) + self.assertEqual(1, len(self.report.errors_by_criticality("WARNING"))) + self.assertEqual(1, len(self.report.errors_by_criticality("INFO"))) check = self.report.checks_by_criticality("ERROR")[0] self.assertEqual(check.name, "check_picture_cpl_max_bitrate")