Coverage for arbejdstimer/cli.py: 100.00%

37 statements  

« prev     ^ index     » next       coverage.py v7.4.1, created at 2024-02-04 15:36:40 +00:00

1"""Commandline API gateway for arbejdstimer.""" 

2 

3import pathlib 

4import sys 

5 

6import typer 

7 

8import arbejdstimer 

9import arbejdstimer.arbejdstimer as at 

10 

11APP_NAME = 'Working hours (Danish arbejdstimer) or not?' 

12APP_ALIAS = 'arbejdstimer' 

13app = typer.Typer( 

14 add_completion=False, 

15 context_settings={'help_option_names': ['-h', '--help']}, 

16 no_args_is_help=True, 

17) 

18 

19TEMPLATE_EXAMPLE = """\ 

20{ 

21 "api": 1, 

22 "application": "arbejdstimer", 

23 "operator": "or", 

24 "holidays": [ 

25 { 

26 "label": "public holiday", 

27 "at": [ 

28 "2022-12-08" 

29 ] 

30 }, 

31 { 

32 "label": "some holidays 2022/2023", 

33 "at": [ 

34 "2022-12-23", 

35 "2023-01-02" 

36 ] 

37 } 

38 ], 

39 "working_hours": [8, 17] 

40} 

41""" 

42 

43 

44@app.callback(invoke_without_command=True) 

45def callback( 

46 version: bool = typer.Option( 

47 False, 

48 '-V', 

49 '--version', 

50 help='Display the arbejdstimer version and exit', 

51 is_eager=True, 

52 ) 

53) -> None: 

54 """ 

55 Working hours (Danish arbejdstimer) or not? 

56 

57 Given a configuration file detect if today is a work day and 

58 if at the time of request is a working hour. 

59 

60 Return code of 0 indicates work time, 1 no work time, and 2 usage error. 

61 

62 Additional help available per command adding the -h/--help option 

63 """ 

64 if version: 

65 typer.echo(f'{APP_NAME} version {arbejdstimer.__version__}') 

66 raise typer.Exit() 

67 

68 

69@app.command('template') 

70def app_template() -> int: 

71 """ 

72 Write a template of a JSON configuration to standard out and exit 

73 """ 

74 sys.stdout.write(TEMPLATE_EXAMPLE) 

75 return sys.exit(0) 

76 

77 

78@app.command('now') 

79def now( 

80 conf: str = typer.Option( 

81 '', 

82 '-c', 

83 '--config', 

84 help='Path to config file (default is $HOME/.arbejdstimer.json)', 

85 metavar='<configpath>', 

86 ), 

87 strict: bool = typer.Option( 

88 False, 

89 '-s', 

90 '--strict', 

91 help='Enforce presence of farming dates in configuration (default is false if not provided)', 

92 metavar='<bool>', 

93 ), 

94) -> int: 

95 """ 

96 Silently answer the question if now is a working hour (per return code 0 for yes, and 1 for no). 

97 """ 

98 command = 'now' 

99 config = conf if conf else pathlib.Path.home() / at.DEFAULT_CONFIG_NAME 

100 action = (command, '', str(config), bool(strict)) 

101 return sys.exit(at.main(action)) 

102 

103 

104def explain_enforce_defaults(conf: str = '', day: str = '', verbose: bool = False, strict: bool = False) -> int: 

105 """Until the root cause of https://github.com/tiangolo/typer/issues/106 remains unfixed.""" 

106 command = 'explain' 

107 if verbose: 

108 command += '_verbatim' 

109 config = conf if conf else pathlib.Path.home() / at.DEFAULT_CONFIG_NAME 

110 action = (command, day, str(config), strict) 

111 return sys.exit(at.main(action)) 

112 

113 

114@app.command('explain') 

115def explain( 

116 conf: str = typer.Option( 

117 '', 

118 '-c', 

119 '--config', 

120 help='Path to config file (default is $HOME/.arbejdstimer.json)', 

121 metavar='<configpath>', 

122 ), 

123 day: str = typer.Option( 

124 '', 

125 '-d', 

126 '--day', 

127 help='Day sought (default is today)', 

128 metavar='<date>', 

129 ), 

130 strict: bool = typer.Option( 

131 False, 

132 '-s', 

133 '--strict', 

134 help='Enforce presence of farming dates in configuration (default is false if not provided)', 

135 metavar='<bool>', 

136 ), 

137 verbose: bool = typer.Option( 

138 False, 

139 '-v', 

140 '--verbose', 

141 help='Be more verbatim providing the effective config values (default is false if not provided)', 

142 metavar='<bool>', 

143 ), 

144) -> int: 

145 """ 

146 Explain the answer to the question if now is a working hour 

147 (in addition to the return code 0 for yes, and 1 for no). 

148 """ 

149 return explain_enforce_defaults(conf, day, verbose, strict) 

150 

151 

152@app.command('version') 

153def app_version() -> None: 

154 """ 

155 Display the arbejdstimer version and exit 

156 """ 

157 callback(True)