Coverage for ajallaan/__init__.py: 0.00%
55 statements
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-04 15:19:53 +00:00
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-04 15:19:53 +00:00
1"""In due time (Finnish: ajallaan) - reporting on worklog entries of some ticket system."""
3import datetime as dti
4import logging
5import os
6import pathlib
7from enum import Enum
8from typing import List, no_type_check
10# [[[fill git_describe()]]]
11__version__ = '2023.4.2+parent.2637a057'
12# [[[end]]] (checksum: 203623ce1610b41c9139f2b591ffc9ff)
13__version_info__ = tuple(
14 e if '-' not in e else e.split('-')[0] for part in __version__.split('+') for e in part.split('.') if e != 'parent'
15)
18class Scope(Enum):
19 LOCAL = 0
20 REMOTE = 1
23APP_ALIAS = str(pathlib.Path(__file__).parent.name)
24APP_ENV = APP_ALIAS.upper()
25APP_NAME = locals()['__doc__']
26DEBUG = bool(os.getenv(f'{APP_ENV}_DEBUG', ''))
27VERBOSE = bool(os.getenv(f'{APP_ENV}_VERBOSE', ''))
28QUIET = False
29STRICT = bool(os.getenv(f'{APP_ENV}_STRICT', ''))
30ENCODING = 'utf-8'
31ENCODING_ERRORS_POLICY = 'ignore'
32DEFAULT_CONFIG_NAME = f'.{APP_ALIAS}.json'
34APP_VERSION = __version__
35COMMA = ','
37API_USER = os.getenv(f'{APP_ENV}_API_USER', '')
38API_TOKEN = os.getenv(f'{APP_ENV}_API_TOKEN', '')
39API_HOST = os.getenv(f'{APP_ENV}_API_HOST', '')
40API_PROTOCOL = os.getenv(f'{APP_ENV}_API_PROTOCOL', 'https')
41API_ROOT = os.getenv(f'{APP_ENV}_API_ROOT', '/rest/com.deniz.jira.worklog/1.0/timesheet/')
42API_PERSPECTIVE = os.getenv(f'{APP_ENV}_API_PERSPECTIVE', 'user')
44WORKLOG_AUTHOR = os.getenv(f'{APP_ENV}_WORKLOG_AUTHOR', '')
46MAX_PACKED_BYTES = int(os.getenv(f'{APP_ENV}_MAX_PACKED_BYTES', '20_000_000'))
47MAX_UNPACKED_BYTES = int(os.getenv(f'{APP_ENV}_MAX_UNPACKED_BYTES', '200_000_000'))
49log = logging.getLogger() # Module level logger is sufficient
50LOG_FOLDER = pathlib.Path('logs')
51LOG_FILE = f'{APP_ALIAS}.log'
52LOG_PATH = pathlib.Path(LOG_FOLDER, LOG_FILE) if LOG_FOLDER.is_dir() else pathlib.Path(LOG_FILE)
53LOG_LEVEL = logging.INFO
54LOG_SEPARATOR = '- ' * 80
57TS_FORMAT_LOG = '%Y-%m-%dT%H:%M:%S'
58TS_FORMAT_PAYLOADS = '%Y-%m-%d %H:%M:%S.%f UTC'
60__all__: List[str] = [
61 'APP_ALIAS',
62 'APP_ENV',
63 'APP_VERSION',
64 'DEBUG',
65 'ENCODING',
66 'LOG_SEPARATOR',
67 'MAX_PACKED_BYTES',
68 'MAX_UNPACKED_BYTES',
69 'QUIET',
70 'STRICT',
71 'TS_FORMAT_PAYLOADS',
72 'VERBOSE',
73 'log',
74 'parse_csl',
75]
78def parse_csl(csl: str) -> List[str]:
79 """DRY."""
80 return [fmt.strip().lower() for fmt in csl.split(COMMA) if fmt.strip()]
83def parse_csl_as_is(csl: str) -> tuple[str, ...]:
84 """DRY."""
85 return tuple(fmt.strip() for fmt in csl.split(COMMA) if fmt.strip())[:2]
88@no_type_check
89def formatTime_RFC3339(self, record, datefmt=None): # noqa
90 """HACK A DID ACK we could inject .astimezone() to localize ..."""
91 return dti.datetime.fromtimestamp(record.created, dti.timezone.utc).isoformat() # pragma: no cover
94@no_type_check
95def init_logger(name=None, level=None):
96 """Initialize module level logger"""
97 global log # pylint: disable=global-statement
99 log_format = {
100 'format': '%(asctime)s %(levelname)s [%(name)s]: %(message)s',
101 'datefmt': TS_FORMAT_LOG,
102 # 'filename': LOG_PATH,
103 'level': LOG_LEVEL if level is None else level,
104 }
105 logging.Formatter.formatTime = formatTime_RFC3339
106 logging.basicConfig(**log_format)
107 log = logging.getLogger(APP_ENV if name is None else name)
108 log.propagate = True
111init_logger(name=APP_ENV, level=logging.DEBUG if DEBUG else None)