From 08097015db2b74ae32b1b3cba4fa59d52e7d27fa Mon Sep 17 00:00:00 2001 From: Petr Stodulka Date: Wed, 11 Oct 2023 13:10:49 +0200 Subject: [PATCH] Report txt: fix printing of non-ascii details Previous commit introduced couple of issues regarding details of reports that could lead to situations like: * remediation instructions has not been printed when non-ascii characters have been present * possible unwanted empty line when remediation has been specified but relative symlinks hasn't * if the URL title contained non-ascii character, it has been broken too (on py2) This should handle all mentioned problems when generating the txt file. --- leapp/utils/report.py | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/leapp/utils/report.py b/leapp/utils/report.py index bbf8f28d6..1ea01221a 100644 --- a/leapp/utils/report.py +++ b/leapp/utils/report.py @@ -116,15 +116,29 @@ def importance(message): return SEVERITY_LEVELS.get(message['severity'], 99) +def _treat_str(text): + """ + Ensure the given text is decoded. + + This is problem in case of Py2 when non-asci characters are present. + """ + return text.decode('utf-8') if isinstance(text, six.binary_type) else text + + def _report_detail_to_string(report_detail): detail = u'' external_links = report_detail[ExternalLink.name] if ExternalLink.name in report_detail.keys() else None remediation = Remediation.from_dict(report_detail) if external_links: - external_links_text = u'Related links:' + external_links_text = u'Related links:\n' for link in external_links: - external_links_text += u'\n - {}: {}'.format(link['title'], link['url']) + # Note(pstodulk): IRI could contain unicode characters. Even when it's + # still unexpected , let's reather treat it as well. + external_links_text += u' - {}: {}\n'.format( + _treat_str(link['title']), + _treat_str(link['url']) + ) detail += external_links_text if remediation: @@ -132,11 +146,8 @@ def _report_detail_to_string(report_detail): # while io.open expects "true text" input. For python3 repr will return proper py3 str, no # decoding will be needed. # This hassle and clumsiness makes me sad, so suggestions are welcome. - remediation_text = '\nRemediation: {}\n'.format(remediation) - if isinstance(remediation_text, six.binary_type): - # This will be true for py2 where repr returns an encoded string - remediation_text = remediation_text.decode('utf-8') - detail += remediation_text + remediation_text = 'Remediation: {}\n'.format(remediation) + detail += _treat_str(remediation_text) return detail @@ -156,8 +167,7 @@ def generate_report_file(messages_to_report, context, path, report_schema='1.1.0 f.write(u'Risk Factor: {} {}\n'.format(message['severity'], flag)) f.write(u'Title: {}\n'.format(message['title'])) f.write(u'Summary: {}\n'.format(message['summary'])) - report_detail = message.get('detail', {}) - detail = _report_detail_to_string(report_detail) + detail = _report_detail_to_string(message.get('detail', {})) f.write(detail) if report_schema_tuple > (1, 0, 0): # report-schema 1.0.0 doesn't have a stable report key