Source code for cioxml.lib.utils

"""Some various utilities."""

from os import remove
from os.path import join, exists, basename
from re import finditer as re_finditer, sub as re_sub
from base64 import b64encode
from json import load as json_load, dumps as json_dumps
from json.decoder import JSONDecodeError

from cioprocessor.lib.utils import select_files
from .i18n import _, translate


# =============================================================================
[docs] def special_protect(content): """Convert special characters (&, <, >) in a secure representation. :param str content: Content to protect. :rtype: str """ return content\ .replace('&amp;', '&').replace(' ', '‧')\ .replace('&lt;', '<').replace('&gt;', '>') \ if content else ''
# =============================================================================
[docs] def special_unprotect(content): """Cancel the protection made by _special_protect(). :param str content: Protected content. :rtype: str """ return content\ .replace('&', '&amp;').replace('‧', ' ')\ .replace('<', '&lt;').replace('>', '&gt;').replace('’', "'") \ if content else ''
# =============================================================================
[docs] def image_base64(pbuild, abs_path, html): """"Replace image source with its content in base64. :type pbuild: .lib.pbuild.PBuild :param pbuild: Current processor build object. :param str abs_path: Absolute path to current directory. :param str html: HTML to process. :rtype: str """ modified = False for match in re_finditer(r'src="((.*)\?cioreplace=(base64))"', html): filename = join(abs_path, match.group(2)) if not exists(filename): pbuild.warning(translate( _('${f} does not exist.', {'f': match.group(2)}), pbuild.lang)) continue with open(filename, 'rb') as hdl: encoded = b64encode(hdl.read()) html = html.replace( match.group(1), 'data:image/png;base64,{0}'.format(encoded.decode("utf-8"))) modified = True return html if modified else None
# =============================================================================
[docs] def remove_css_maps(pbuild, step): """Remove CSS maps and their call. :type build: cioprocessor.lib.build.PBuild :param build: Current build object. :param dict step: Dictionary defining the current step. """ if not pbuild.current['values'].get('remove_css_map'): return if 'select' not in step: step['select'] = '\\.css$' for path in select_files(pbuild, step): map_file = '{}.map'.format(path) if exists(map_file): remove(map_file) with open(path, 'r', encoding='utf8') as hdl: content = hdl.read() content = re_sub('/\\*# sourceMappingURL=[^*]+\\*/', '', content) with open(path, 'w', encoding='utf8') as hdl: hdl.write(content)
# =============================================================================
[docs] def ajust_css_maps(pbuild, step): """Ajust CSS maps and their call. :type build: cioprocessor.lib.build.PBuild :param build: Current build object. :param dict step: Dictionary defining the current step. """ if 'select' not in step: step['select'] = '\\.css$' for path in select_files(pbuild, step): with open(path, 'r', encoding='utf8') as hdl: content = hdl.read() content = re_sub( '/\\*# sourceMappingURL=[^*]+\\*/', f'/*# sourceMappingURL={basename(path)}.map */', content) with open(path, 'w', encoding='utf8') as hdl: hdl.write(content)
# =============================================================================
[docs] def pretty_print_json(pbuild, step): """Pretty print JSON files. :type build: cioprocessor.lib.build.PBuild :param build: Current build object. :param dict step: Dictionary defining the current step. :rtype: bool """ if 'select' not in step: step['select'] = '\\.json$' has_error = False for path in select_files(pbuild, step): with open(path, 'r', encoding='utf8') as hdl: try: json = json_load(hdl) except (OSError, JSONDecodeError) as error: pbuild.error(translate( _('JSON: ${e}', {'e': error}), pbuild.lang)) has_error = True continue with open(path, 'w', encoding='utf8') as hdl: hdl.write(json_dumps(json, indent=4, ensure_ascii=False)) return has_error