Source code for webdriver_test_tools.common.files

"""Common functions for working with files and Jinja templates"""

import os
import re

import jinja2

# Exceptions

[docs]class FileUtilError(Exception): """Exception raised if utility functions fail""" pass
# File utility functions
[docs]def touch(filepath): """'Touch' a file. Creates an empty file if it doesn't exist, leaves existing files unchanged :param filepath: Path of the file to touch """ open(filepath, 'a').close()
[docs]def create_directory(target_path, directory_name): """Creates a directory in the target path if it doesn't already exist :param target_path: The path to the directory that will contain the new one :param directory_name: The name of the directory to create in the target path :return: The path to the newly created (or already existing) directory """ path = os.path.join(target_path, directory_name) if not os.path.exists(path): os.makedirs(path) return path
# Template utility functions
[docs]def render_template(template_path, context): """Returns the rendered contents of a jinja template :param template_path: The path to the jinja template :param context: Jinja context used to render template :return: Results of rendering jinja template """ path, filename = os.path.split(template_path) return jinja2.Environment( loader=jinja2.FileSystemLoader(path or './'), trim_blocks=True, lstrip_blocks=True ).get_template(filename).render(context)
[docs]def render_template_to_file(template_path, context, target_path): """Writes rendered jinja template to a file :param template_path: The path to the jinja template :param context: Jinja context used to render template :param target_path: File path to write the rendered template to """ with open(target_path, 'w') as f: file_contents = render_template(template_path, context) f.write(file_contents)
[docs]def create_file_from_template(template_path, target_path, filename, context, target_filename=None, overwrite=True): """Short hand function that renders a template with the specified filename followed by a '.j2' extension from the template path to a file with the specified name in the target path The use of '.j2' as a file extension is to distinguish templates from package modules. :param template_path: Path to template directory :param target_path: Path to target directory :param filename: Name of the template file. Will be used as the filename for the rendered file written to the target directory :param context: Jinja context used to render template :param target_filename: (Optional) If specified, use a different filename for the created file. If not specified, will use the value of ``filename`` :param overwrite: (Default: True) If False, a FileUtilError will be raised when a file with the same name and path already exists :return: The file path to the newly created file """ if target_filename is None: target_filename = filename file_template = os.path.join(template_path, filename + '.j2') file_target = os.path.join(target_path, target_filename) if not overwrite and os.path.exists(file_target): message_format = 'File "{}" already exists' raise FileUtilError(message_format.format(file_target)) render_template_to_file(file_template, context, file_target) return file_target
# Validation
[docs]def validate_filename(filename, allow_spaces=False): """Strips invalid characters from a filename Considers `POSIX "fully portable filenames" <>`__ valid. These include: A-Z a-z 0-9 ._- Filenames cannot begin with a hyphen. :param filename: The desired file name (without path) :param allow_spaces: (Default = False) If True, spaces will be considered valid characters :return: Filename with invalid characters removed """ regex = r'^-|[^\d\w\. -]' if allow_spaces else r'^-|[^\d\w\.-]' return re.sub(regex, '', filename)