Coverage for muuntaa/__init__.py: 100.00%
44 statements
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-04 20:39:23 +00:00
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-04 20:39:23 +00:00
1"""Convert (Finnish: muuntaa) CVRF v1.2 XML to CSAF v2.0 JSON documents."""
3import datetime as dti
4import logging
5import os
6import pathlib
7from typing import Union, no_type_check
9# [[[fill git_describe()]]]
10__version__ = '2024.1.9+parent.abadcafe'
11# [[[end]]]
12__version_info__ = tuple(
13 e if '-' not in e else e.split('-')[0] for part in __version__.split('+') for e in part.split('.') if e != 'parent'
14)
16APP_ALIAS = str(pathlib.Path(__file__).parent.name)
17APP_ENV = APP_ALIAS.upper()
18APP_NAME = locals()['__doc__']
19DEBUG = bool(os.getenv(f'{APP_ENV}_DEBUG', ''))
20ENCODING = 'utf-8'
21ENCODING_ERRORS_POLICY = 'ignore'
22DEFAULT_CONFIG_NAME = f'.{APP_ALIAS}.yml'
23log = logging.getLogger() # Module level logger is sufficient
24LOG_FOLDER = pathlib.Path('logs')
25LOG_FILE = f'{APP_ALIAS}.log'
26LOG_PATH = pathlib.Path(LOG_FOLDER, LOG_FILE) if LOG_FOLDER.is_dir() else pathlib.Path(LOG_FILE)
27LOG_LEVEL = logging.INFO
28VERSION = __version__
29VERSION_DOTTED_TRIPLE = '.'.join(__version_info__[:3])
30TS_FORMAT_LOG = '%Y-%m-%dT%H:%M:%S'
31BOOLEAN_KEYS = ('force', 'fix_insert_current_version_into_revision_history')
32INPUT_FILE_KEY = 'input_file'
33NOW_CODE = 'now'
34OVERWRITABLE_KEYS = [
35 'fix_insert_current_version_into_revision_history',
36 'force_insert_default_reference_category',
37 'remove_CVSS_values_without_vector',
38 'force',
39]
40CSAF_FILE_SUFFIX = '.json'
42ConfigType = dict[str, Union[None, bool, int, float, str]]
43LogLevel = int
44Pathlike = Union[pathlib.Path, str]
45ScopedMessage = tuple[LogLevel, str]
46ScopedMessages = list[ScopedMessage]
47WriterOptions = Union[None, dict[str, Union[bool, int]]]
49__all__: list[str] = [
50 'APP_ALIAS',
51 'APP_ENV',
52 'APP_NAME',
53 'BOOLEAN_KEYS',
54 'CSAF_FILE_SUFFIX',
55 'DEBUG',
56 'DEFAULT_CONFIG_NAME',
57 'ConfigType',
58 'ENCODING',
59 'ENCODING_ERRORS_POLICY',
60 'INPUT_FILE_KEY',
61 'LogLevel',
62 'NOW_CODE',
63 'OVERWRITABLE_KEYS',
64 'Pathlike',
65 'ScopedMessage',
66 'ScopedMessages',
67 'VERSION',
68 'VERSION_DOTTED_TRIPLE',
69 'WriterOptions',
70 'log',
71]
74@no_type_check
75def formatTime_RFC3339(self, record, datefmt=None): # noqa
76 """HACK A DID ACK we could inject .astimezone() to localize ..."""
77 return dti.datetime.fromtimestamp(record.created, dti.timezone.utc).isoformat() # pragma: no cover
80@no_type_check
81def init_logger(name=None, level=None):
82 """Initialize module level logger"""
83 global log # pylint: disable=global-statement
85 log_format = {
86 'format': '%(asctime)s %(levelname)s [%(name)s]: %(message)s',
87 'datefmt': TS_FORMAT_LOG,
88 # 'filename': LOG_PATH,
89 'level': LOG_LEVEL if level is None else level,
90 }
91 logging.Formatter.formatTime = formatTime_RFC3339
92 logging.basicConfig(**log_format)
93 log = logging.getLogger(APP_ENV if name is None else name)
94 log.propagate = True
97init_logger(name=APP_ENV, level=logging.DEBUG if DEBUG else None)