Coverage for etiketti/__init__.py: 86.49%
64 statements
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-04 17:54:24 +00:00
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-04 17:54:24 +00:00
1"""Label (Finnish: etiketti) some files."""
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.16+parent.g0a2f67d3'
11# [[[end]]] (checksum: e04ad0c0084645e3a7b0cdf9c3f06a99)
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', ''))
20VERBOSE = bool(os.getenv(f'{APP_ENV}_VERBOSE', ''))
21QUIET = False
22STRICT = bool(os.getenv(f'{APP_ENV}_STRICT', ''))
23ENCODING = 'utf-8'
24ENCODING_ERRORS_POLICY = 'ignore'
25DEFAULT_CONFIG_NAME = f'.{APP_ALIAS}.json'
27APP_VERSION = __version__
28DEFAULT_LF_ONLY = 'YES'
29DEFAULT_AUTHOR = os.getenv(f'{APP_ENV}_DEFAULT_AUTHOR', '')
30log = logging.getLogger() # Module level logger is sufficient
31LOG_FOLDER = pathlib.Path('logs')
32LOG_FILE = f'{APP_ALIAS}.log'
33LOG_PATH = pathlib.Path(LOG_FOLDER, LOG_FILE) if LOG_FOLDER.is_dir() else pathlib.Path(LOG_FILE)
34LOG_LEVEL = logging.INFO
36COMMA = ','
37EQUAL = '='
39LOG_SEPARATOR = '- ' * 80
40INTER_PROCESS_SYNC_SECS = 0.1
41INTER_PROCESS_SYNC_ATTEMPTS = 10
42TS_FORMAT_ISO = '%Y-%m-%dT%H:%M:%SZ'
43TS_FORMAT_PDF = '%Y%m%dT%H%M%SZ' # was 'D:%Y%m%dT%H%M%SZ'
44TS_FORMAT_LOG = '%Y-%m-%dT%H:%M:%S'
45TS_FORMAT_PAYLOADS = '%Y-%m-%d %H:%M:%S.%f UTC'
46TS_FORMAT_PATCH = '%Y-%m-%d %H:%M:%S'
48SOURCE_NAME_PATH_STRING = os.getenv(f'{APP_ENV}_SOURCE_NAME_PATH_STRING', 'this.pdf')
49TARGET_NAME_PATH_STRING = os.getenv(f'{APP_ENV}_TARGET_NAME_PATH_STRING', 'labeled.pdf')
50CONFIG_PATH_STRING = os.getenv(f'{APP_ENV}_CONFIG_PATH_STRING', f'/opt/label/{APP_ALIAS}.yml')
52ContextType = dict[str, dict[str, str]]
53ConventionsType = dict[str, pathlib.Path]
54PathLike = Union[str, pathlib.Path]
56__all__: list[str] = [
57 'APP_ALIAS',
58 'APP_ENV',
59 'APP_NAME',
60 'APP_VERSION',
61 'CONFIG_PATH_STRING',
62 'DEFAULT_AUTHOR',
63 'ENCODING',
64 'LOG_SEPARATOR',
65 'SOURCE_NAME_PATH_STRING',
66 'TARGET_NAME_PATH_STRING',
67 'TS_FORMAT_PATCH',
68 'TS_FORMAT_PAYLOADS',
69 'TS_FORMAT_ISO',
70 'ContextType',
71 'ConventionsType',
72 'PathLike',
73 'log',
74 'parse_key_value_pair_csl',
75]
78def parse_key_value_pair_csl(csl: str) -> dict[str, str]:
79 """DRY."""
80 pairs = [pair.strip() for pair in csl.split(COMMA) if pair.strip() and EQUAL in pair]
81 key_value_store = {}
82 for pair in pairs: 82 ↛ 83line 82 didn't jump to line 83, because the loop on line 82 never started
83 try:
84 k, v = pair.split(EQUAL, 1)
85 except ValueError:
86 continue
87 real_key = k.strip()
88 if real_key:
89 key_value_store[real_key] = v.strip()
90 return key_value_store
93@no_type_check
94def formatTime_RFC3339(self, record, datefmt=None): # noqa
95 """HACK A DID ACK we could inject .astimezone() to localize ..."""
96 return dti.datetime.fromtimestamp(record.created, dti.timezone.utc).isoformat() # pragma: no cover
99@no_type_check
100def init_logger(name=None, level=None):
101 """Initialize module level logger"""
102 global log # pylint: disable=global-statement
104 log_format = {
105 'format': '%(asctime)s %(levelname)s [%(name)s]: %(message)s',
106 'datefmt': TS_FORMAT_LOG,
107 # 'filename': LOG_PATH,
108 'level': LOG_LEVEL if level is None else level,
109 }
110 logging.Formatter.formatTime = formatTime_RFC3339
111 logging.basicConfig(**log_format)
112 log = logging.getLogger(APP_ENV if name is None else name)
113 log.propagate = True
116init_logger(name=APP_ENV, level=logging.DEBUG if DEBUG else None)