1 1
import os
2 1
import json
3 1
import inspect
4 1
import importlib
5 1
import re
6 1
import pkg_resources
7

8 1
from six import string_types
9 1
import ruamel.yaml as yaml
10

11
# python 2/3 compatibility
12 1
try:
13 1
    import pathlib
14 0
except ImportError:
15 0
    import pathlib2 as pathlib
16

17

18 1
def handle_error(msg, err_type, logger, raise_msg=None, log_msg=None):
19
    """handle an error, by logging it, then raising an exception"""
20 1
    if raise_msg is None:
21 1
        raise_msg = msg
22 1
    if log_msg is None:
23 1
        log_msg = msg
24

25 1
    logger.error(log_msg)
26 1
    raise err_type(raise_msg)
27

28

29 1
def read_file_from_directory(
30
    dir_path,
31
    file_name,
32
    jtype,
33
    logger,
34
    interp_ext=False,
35
    ext_types=(("json", (".json",)), ("yaml", (".yaml", ".yaml.j2"))),
36
):
37
    """load a file situated in a directory
38

39
    if ``interp_ext=True``:
40
    interpret the file extension *via* ``ext_types``
41
    and load file in a suitable manner
42

43
    """
44 1
    if isinstance(dir_path, string_types):
45 1
        dir_path = pathlib.Path(dir_path)
46

47 1
    file_path = dir_path.joinpath(file_name)
48

49 1
    if not file_path.exists():
50 0
        handle_error(
51
            "the {} does not exist: {}".format(jtype, file_path), IOError, logger=logger
52
        )
53

54 1
    ext_type = None
55 1
    ext_map = {ext: ftype for ftype, exts in ext_types for ext in exts}
56
    # Place longer extensions first to keep shorter ones from matching first
57 1
    for ext in sorted(ext_map.keys(), key=len, reverse=True):
58 1
        if file_name.endswith(ext):
59 1
            ext_type = ext_map[ext]
60

61 1
    if ext_type is not None and interp_ext:
62 1
        with file_path.open() as fobj:
63 1
            try:
64 1
                if ext_type == "json":
65 1
                    data = json.load(fobj)
66 1
                elif ext_type == "yaml":
67 1
                    data = yaml.safe_load(fobj)
68
                else:
69 0
                    raise ValueError("extension type not recognised")
70 0
            except Exception as err:
71 0
                handle_error(
72
                    "failed to read {} ({}): {}".format(jtype, file_path, err),
73
                    IOError,
74
                    logger=logger,
75
                )
76
    else:
77 1
        with file_path.open() as fobj:
78 1
            data = fobj.read()
79

80 1
    return data
81

82

83 1
def get_module_path(module):
84
    """return a directory path to a module"""
85 1
    return pathlib.Path(os.path.dirname(os.path.abspath(inspect.getfile(module))))
86

87

88 1
def read_file_from_module(
89
    module_path,
90
    file_name,
91
    jtype,
92
    logger,
93
    interp_ext=False,
94
    ext_types=(("json", (".json")), ("yaml", (".yaml", ".yaml.j2", "yaml.tex.j2"))),
95
):
96
    """load a file situated in a python module
97

98
    if ``interp_ext=True``:
99
    interpret the file extension *via* ``ext_type``
100
    and load file in a suitable manner
101

102
    """
103 1
    try:
104 1
        outline_module = importlib.import_module(module_path)
105 0
    except ModuleNotFoundError:  # noqa: F821
106 0
        handle_error(
107
            "module {} containing {} {} not found".format(
108
                module_path, jtype, file_name
109
            ),
110
            ModuleNotFoundError,
111
            logger=logger,
112
        )  # noqa: F821
113

114 1
    return read_file_from_directory(
115
        get_module_path(outline_module),
116
        file_name,
117
        jtype,
118
        logger,
119
        interp_ext=interp_ext,
120
        ext_types=ext_types,
121
    )
122

123

124 1
def get_valid_filename(s):
125
    """
126
    Return the given string converted to a string that can be used for a clean
127
    filename. Remove leading and trailing spaces; convert other spaces to
128
    underscores; and remove anything that is not an alphanumeric, dash,
129
    underscore, or dot.
130
    >>> get_valid_filename("john's portrait in 2004.jpg")
131
    'johns_portrait_in_2004.jpg'
132
    """
133 1
    s = str(s).strip().replace(" ", "_")
134 1
    return re.sub(r"(?u)[^-\w.]", "", s)
135

136

137 1
def find_entry_point(name, group, logger, preferred=None):
138
    """find an entry point by name and group
139

140
    Parameters
141
    ----------
142
    name: str
143
        name of entry point
144
    group: str
145
        group of entry point
146
    preferred: str
147
        if multiple matches are found, prefer one from this module
148

149
    """
150 1
    entry_points = list(pkg_resources.iter_entry_points(group, name))
151 1
    if len(entry_points) == 0:
152 0
        handle_error(
153
            "The {0} entry point " "{1} could not be found".format(group, name),
154
            pkg_resources.ResolutionError,
155
            logger,
156
        )
157 1
    elif len(entry_points) != 1:
158
        # default to the preferred package
159 0
        oentry_points = []
160 0
        if preferred:
161 0
            oentry_points = [
162
                ep for ep in entry_points if ep.module_name.startswith(preferred)
163
            ]
164 0
        if len(oentry_points) != 1:
165 0
            handle_error(
166
                "Multiple {0} plugins found for "
167
                "{1}: {2}".format(group, name, entry_points),
168
                pkg_resources.ResolutionError,
169
                logger,
170
            )
171 0
        logger.info(
172
            "Multiple {0} plugins found for {1}, "
173
            "defaulting to the {2} version".format(group, name, preferred)
174
        )
175 0
        entry_point = oentry_points[0]
176
    else:
177 1
        entry_point = entry_points[0]
178 1
    return entry_point.load()

Read our documentation on viewing source code .

Loading