Coverage for piemap/__init__.py: 100.00%

69 statements  

« prev     ^ index     » next       coverage.py v7.4.1, created at 2024-02-04 21:26:31 +00:00

1"""One-view visualization of grouped characterizations (Quality Pie).""" 

2 

3import datetime as dti 

4import logging 

5import os 

6import pathlib 

7from typing import no_type_check 

8 

9# [[[fill git_describe()]]] 

10__version__ = '2023.10.22+parent.ed38dfeb' 

11# [[[end]]] (checksum: db573b62f771dae6170699431794e7d5) 

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) 

15__all__: list[str] = [ 

16 'ANGLE_MAX', 

17 'ANGLE_OFF', 

18 'CIRCLE_CENTER', 

19 'DARKRED', 

20 'DEBUG', 

21 'ENCODING', 

22 'ENCODING_ERRORS_POLICY', 

23 'GRAY', 

24 'GREEN', 

25 'HEIGHT', 

26 'HEIGHT_HALF', 

27 'HEIGHT_OFF', 

28 'LABEL_SIZE', 

29 'LINE_WIDTH', 

30 'PIE_BOX', 

31 'RADIUS', 

32 'RADIUS_HALF', 

33 'RED', 

34 'SUBTITLE_SIZE', 

35 'TITLE_SIZE', 

36 'TOP_LEFT_X', 

37 'TOP_LEFT_Y', 

38 'WHITE', 

39 'WIDTH', 

40 'WIDTH_HALF', 

41 'WIDTH_OFF', 

42 'YELLOW', 

43 'YELLOWGREEN', 

44 'log', 

45] 

46 

47APP_ALIAS = str(pathlib.Path(__file__).parent.name) 

48APP_ENV = APP_ALIAS.upper() 

49APP_NAME = locals()['__doc__'] 

50DEBUG = bool(os.getenv(f'{APP_ENV}_DEBUG', '')) 

51VERBOSE = bool(os.getenv(f'{APP_ENV}_VERBOSE', '')) 

52QUIET = False 

53STRICT = bool(os.getenv(f'{APP_ENV}_STRICT', '')) 

54ENCODING = 'utf-8' 

55ENCODING_ERRORS_POLICY = 'ignore' 

56DEFAULT_CONFIG_NAME = f'.{APP_ALIAS}.json' 

57 

58COLON = ':' 

59COMMA = ',' 

60DEFAULT_LF_ONLY = 'YES' 

61DOT = '.' 

62KNOWN_FORMATS = ('jpeg', 'png', 'svg') 

63PIPE = '|' 

64SEMI = ';' 

65 

66log = logging.getLogger() # Module level logger is sufficient 

67LOG_FOLDER = pathlib.Path('logs') 

68LOG_FILE = f'{APP_ALIAS}.log' 

69LOG_PATH = pathlib.Path(LOG_FOLDER, LOG_FILE) if LOG_FOLDER.is_dir() else pathlib.Path(LOG_FILE) 

70LOG_LEVEL = logging.INFO 

71 

72TS_FORMAT_LOG = '%Y-%m-%dT%H:%M:%S' 

73TS_FORMAT_PAYLOADS = '%Y-%m-%d %H:%M:%S.%f UTC' 

74 

75WIDTH = 1080 

76HEIGHT = WIDTH 

77DIAMETER = 900 

78WIDTH_HALF = WIDTH / 2 

79HEIGHT_HALF = HEIGHT / 2 

80RADIUS = DIAMETER / 2 

81WIDTH_OFF = 0 

82HEIGHT_OFF = 50 

83TOP_LEFT_X = WIDTH_HALF - RADIUS 

84TOP_LEFT_Y = HEIGHT_HALF - RADIUS + HEIGHT_OFF 

85PIE_BOX = ((TOP_LEFT_X, TOP_LEFT_Y), (TOP_LEFT_X + DIAMETER, TOP_LEFT_Y + DIAMETER)) 

86CIRCLE_CENTER = (WIDTH_HALF, HEIGHT_HALF + HEIGHT_OFF) 

87 

88ANGLE_OFF = 270 

89ANGLE_MAX = 360 

90 

91# font sizes and line width 

92TITLE_SIZE = 40 

93SUBTITLE_SIZE = 24 

94LABEL_SIZE = 16 

95LINE_WIDTH = 1 

96 

97# colors 

98DARKRED = '#900000' 

99GRAY = '#c0c0c0' 

100GREEN = '#008800' 

101RED = '#dd0000' 

102WHITE = '#ffffff' 

103YELLOW = '#ffff20' 

104YELLOWGREEN = '#77ff20' 

105 

106 

107def parse_csl(csl: str) -> list[str]: 

108 """DRY.""" 

109 return [fmt.strip().lower() for fmt in csl.split(COMMA) if fmt.strip()] 

110 

111 

112@no_type_check 

113def formatTime_RFC3339(self, record, datefmt=None): # noqa 

114 """HACK A DID ACK we could inject .astimezone() to localize ...""" 

115 return dti.datetime.fromtimestamp(record.created, dti.timezone.utc).isoformat() # pragma: no cover 

116 

117 

118@no_type_check 

119def init_logger(name=None, level=None): 

120 """Initialize module level logger""" 

121 global log # pylint: disable=global-statement 

122 

123 log_format = { 

124 'format': '%(asctime)s %(levelname)s [%(name)s]: %(message)s', 

125 'datefmt': TS_FORMAT_LOG, 

126 # 'filename': LOG_PATH, 

127 'level': LOG_LEVEL if level is None else level, 

128 } 

129 logging.Formatter.formatTime = formatTime_RFC3339 

130 logging.basicConfig(**log_format) 

131 log = logging.getLogger(APP_ENV if name is None else name) 

132 log.propagate = True 

133 

134 

135init_logger(name=APP_ENV, level=logging.DEBUG if DEBUG else None)