Commit e280210d by dorp

Uncle Bobbed the filter plus other requested changes

parent 653701f3
import logging import logging
from base64 import decodebytes from base64 import decodebytes
from collections import OrderedDict from collections import OrderedDict
from contextlib import suppress
from pathlib import Path from pathlib import Path
from time import localtime, strftime from time import localtime, strftime
...@@ -10,39 +11,32 @@ from common_helper_files import human_readable_file_size ...@@ -10,39 +11,32 @@ from common_helper_files import human_readable_file_size
GENERIC_TEMPLATE = 'generic.tex' GENERIC_TEMPLATE = 'generic.tex'
def byte_number_filter(number, verbose=True): def render_number_as_size(number, verbose=True):
if isinstance(number, (int, float)): if not isinstance(number, (int, float)):
if verbose: return 'not available'
return '{} ({})'.format(human_readable_file_size(int(number)), format(number, ',d') + ' Byte') if verbose:
return human_readable_file_size(int(number)) return '{} ({})'.format(human_readable_file_size(int(number)), format(number, ',d') + ' Byte')
return 'not available' return human_readable_file_size(int(number))
def nice_unix_time(unix_time_stamp): def render_unix_time(unix_time_stamp):
''' if not isinstance(unix_time_stamp, (int, float)):
input unix_time_stamp return 'not available'
output string 'YYYY-MM-DD HH:MM:SS' return strftime('%Y-%m-%d %H:%M:%S', localtime(unix_time_stamp))
'''
if isinstance(unix_time_stamp, (int, float)):
tmp = localtime(unix_time_stamp)
return strftime('%Y-%m-%d %H:%M:%S', tmp)
return 'not available'
def nice_number_filter(number): def render_number_as_string(number):
if isinstance(number, int): if isinstance(number, int):
return '{:,}'.format(number) return '{:,}'.format(number)
if isinstance(number, float): if isinstance(number, float):
return '{:,.2f}'.format(number) return '{:,.2f}'.format(number)
if isinstance(number, str): if isinstance(number, str):
try: with suppress(ValueError):
return str(int(number)) return str(int(number))
except ValueError:
pass
return 'not available' return 'not available'
def filter_latex_special_chars(data): def replace_special_characters(data):
latex_character_escapes = OrderedDict() latex_character_escapes = OrderedDict()
latex_character_escapes['\\'] = '' latex_character_escapes['\\'] = ''
latex_character_escapes['\''] = '' latex_character_escapes['\''] = ''
...@@ -69,34 +63,31 @@ def filter_latex_special_chars(data): ...@@ -69,34 +63,31 @@ def filter_latex_special_chars(data):
return data return data
def convert_base64_to_png_filter(base64_string, filename, directory): def decode_base64_to_file(base64_string, filename, directory, suffix='png'):
file_path = Path(directory, filename + '.png') file_path = Path(directory, '{}.{}'.format(filename, suffix))
file_path.write_bytes(decodebytes(base64_string.encode('utf-8'))) file_path.write_bytes(decodebytes(base64_string.encode('utf-8')))
return str(file_path) return str(file_path)
def filter_chars_in_list(list_of_strings): def replace_characters_in_list(list_of_strings):
return [ return [
filter_latex_special_chars(item) for item in list_of_strings replace_special_characters(item) for item in list_of_strings
] ]
def split_hash(hash_value, max_length=61): def split_hash_string(hash_string, max_length=61):
if len(hash_value) > max_length: if len(hash_string) > max_length:
hash_value = '{} {}'.format(hash_value[:max_length], hash_value[max_length:]) hash_string = '{}\n{}'.format(hash_string[:max_length], hash_string[max_length:])
return hash_value return hash_string
def split_output_lines(output_value, max_length=92): def split_long_lines(multiline_string, max_length=92):
lines = output_value.splitlines(keepends=True) def evaluate_split(line):
output = '' return line if len(line) <= max_length else '{}\n{}'.format(line[:max_length], line[max_length:])
for line in lines: return ''.join(
if len(line) > max_length: evaluate_split(line) for line in multiline_string.splitlines(keepends=True)
line = '{} {}'.format(line[:max_length], line[max_length:]) )
output += line
return output
def item_contains_string(item, string): def item_contains_string(item, string):
...@@ -125,22 +116,21 @@ def create_jinja_environment(templates_to_use='default'): ...@@ -125,22 +116,21 @@ def create_jinja_environment(templates_to_use='default'):
def plugin_name(name): def plugin_name(name):
parts = name.split('_') return ' '.join((part.title() for part in name.split('_')))
return ' '.join(('{}{}'.format(part[0:1].upper(), part[1:]) for part in parts))
def _add_filters_to_jinja(environment): def _add_filters_to_jinja(environment):
environment.filters['number_format'] = byte_number_filter environment.filters['number_format'] = render_number_as_size
environment.filters['nice_unix_time'] = nice_unix_time environment.filters['nice_unix_time'] = render_unix_time
environment.filters['nice_number'] = nice_number_filter environment.filters['nice_number'] = render_number_as_string
environment.filters['filter_chars'] = filter_latex_special_chars environment.filters['filter_chars'] = replace_special_characters
environment.filters['elements_count'] = len environment.filters['elements_count'] = len
environment.filters['base64_to_png'] = convert_base64_to_png_filter environment.filters['base64_to_png'] = decode_base64_to_file
environment.filters['check_list'] = lambda x: x if x else ['list is empty'] environment.filters['check_list'] = lambda x: x if x else ['list is empty']
environment.filters['plugin_name'] = plugin_name environment.filters['plugin_name'] = plugin_name
environment.filters['filter_list'] = filter_chars_in_list environment.filters['filter_list'] = replace_characters_in_list
environment.filters['split_hash'] = split_hash environment.filters['split_hash'] = split_hash_string
environment.filters['split_output_lines'] = split_output_lines environment.filters['split_output_lines'] = split_long_lines
environment.filters['contains'] = item_contains_string environment.filters['contains'] = item_contains_string
......
import json import json
from pathlib import Path from pathlib import Path
import pytest
from pdf_generator.generator import ( from pdf_generator.generator import (
copy_fact_image, create_report_filename, create_templates, execute_latex, render_analysis_templates copy_fact_image, create_report_filename, create_templates, execute_latex, render_analysis_templates
) )
...@@ -40,10 +41,13 @@ def test_copy_fact_image(tmpdir): ...@@ -40,10 +41,13 @@ def test_copy_fact_image(tmpdir):
assert Path(str(tmpdir), 'fact_logo.png').exists() assert Path(str(tmpdir), 'fact_logo.png').exists()
def test_create_report_filename(): @pytest.mark.parametrize('device_name, pdf_name', [
assert create_report_filename({'device_name': 'simple'}) == 'simple_analysis_report.pdf' ('simple', 'simple_analysis_report.pdf'),
assert create_report_filename({'device_name': 'harder name'}) == 'harder_name_analysis_report.pdf' ('harder name', 'harder_name_analysis_report.pdf'),
assert create_report_filename({'device_name': 'dangerous/name'}) == 'dangerous__name_analysis_report.pdf' ('dangerous/name', 'dangerous__name_analysis_report.pdf')
])
def test_create_report_filename(device_name, pdf_name):
assert create_report_filename({'device_name': device_name}) == pdf_name
def test_create_analysis_templates(): def test_create_analysis_templates():
......
...@@ -2,8 +2,8 @@ from pathlib import Path ...@@ -2,8 +2,8 @@ from pathlib import Path
import pytest import pytest
from pdf_generator.tex_generation.template_engine import ( from pdf_generator.tex_generation.template_engine import (
TemplateEngine, byte_number_filter, convert_base64_to_png_filter, filter_chars_in_list, filter_latex_special_chars, TemplateEngine, decode_base64_to_file, render_number_as_size, render_number_as_string, render_unix_time,
nice_number_filter, nice_unix_time, split_hash, split_output_lines replace_characters_in_list, replace_special_characters, split_hash_string, split_long_lines
) )
# pylint: disable=redefined-outer-name # pylint: disable=redefined-outer-name
...@@ -15,57 +15,57 @@ def stub_engine(tmpdir): ...@@ -15,57 +15,57 @@ def stub_engine(tmpdir):
def test_byte_number_filter(): def test_byte_number_filter():
assert byte_number_filter(None) == 'not available' assert render_number_as_size(None) == 'not available'
assert byte_number_filter(12, verbose=False) == '12.00 Byte' assert render_number_as_size(12, verbose=False) == '12.00 Byte'
assert byte_number_filter(128000) == '125.00 KiB (128,000 Byte)' assert render_number_as_size(128000) == '125.00 KiB (128,000 Byte)'
assert byte_number_filter(128000, verbose=False) == '125.00 KiB' assert render_number_as_size(128000, verbose=False) == '125.00 KiB'
def test_nice_number_filter(): def test_nice_number_filter():
assert nice_number_filter(None) == 'not available' assert render_number_as_string(None) == 'not available'
assert nice_number_filter('no int') == 'not available' assert render_number_as_string('no int') == 'not available'
assert nice_number_filter(12) == '12' assert render_number_as_string(12) == '12'
assert nice_number_filter(12.1) == '12.10' assert render_number_as_string(12.1) == '12.10'
assert nice_number_filter(12.101) == '12.10' assert render_number_as_string(12.101) == '12.10'
assert nice_number_filter(12.109) == '12.11' assert render_number_as_string(12.109) == '12.11'
assert nice_number_filter('12') == '12' assert render_number_as_string('12') == '12'
@pytest.mark.skip(reason='Since local time used, result is not stable') @pytest.mark.skip(reason='Since local time used, result is not stable')
def test_nice_unix_time(): def test_nice_unix_time():
assert nice_unix_time(None) == 'not available' assert render_unix_time(None) == 'not available'
assert nice_unix_time(10) == '1970-01-01 01:00:10' assert render_unix_time(10) == '1970-01-01 01:00:10'
def test_split_hash(): def test_split_hash():
assert split_hash('X' * 62) == '{} X'.format('X' * 61) assert split_hash_string('X' * 62) == '{}\nX'.format('X' * 61)
assert split_hash('X' * 61) == 'X' * 61 assert split_hash_string('X' * 61) == 'X' * 61
def test_split_output_lines(): def test_split_output_lines():
assert split_output_lines('X\nX') == 'X\nX' assert split_long_lines('X\nX') == 'X\nX'
assert split_output_lines('{}\nX'.format('X' * 93)) == '{} X\nX'.format('X' * 92) assert split_long_lines('{}\nX'.format('X' * 93)) == '{}\nX\nX'.format('X' * 92)
def test_convert_base64_to_png_filter(tmpdir): def test_convert_base64_to_png_filter(tmpdir):
convert_base64_to_png_filter('0000', 'testfile', str(tmpdir)) decode_base64_to_file('0000', 'testfile', str(tmpdir))
assert Path(str(tmpdir), 'testfile.png').read_bytes() == b'\xd3\x4d\x34' assert Path(str(tmpdir), 'testfile.png').read_bytes() == b'\xd3\x4d\x34'
def test_filter_latex_special_chars(): def test_filter_latex_special_chars():
assert filter_latex_special_chars('safe') == 'safe' assert replace_special_characters('safe') == 'safe'
assert filter_latex_special_chars(r'C:\Windows') == r'C:Windows' assert replace_special_characters(r'C:\Windows') == r'C:Windows'
assert filter_latex_special_chars(r'100 $') == r'100 \$' assert replace_special_characters(r'100 $') == r'100 \$'
def test_filter_chars_in_list(): def test_filter_chars_in_list():
assert filter_chars_in_list([]) == [] assert replace_characters_in_list([]) == []
assert filter_chars_in_list([r'safe', r'un\safe']) == ['safe', 'unsafe'] assert replace_characters_in_list([r'safe', r'un\safe']) == ['safe', 'unsafe']
def test_render_meta_template(stub_engine): def test_render_meta_template(stub_engine):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment