4
4
import itertools
5
5
import json
6
6
import operator
7
- import re
8
7
9
8
from dateutil import tz
10
9
from functools import reduce , wraps
@@ -70,15 +69,17 @@ def _raise_exclusive_error(self):
70
69
['`--{}`' .format (_ ) for _ in self .mutually_exclusive ]))))
71
70
72
71
73
- class DateParamType (click .ParamType ):
74
- name = 'date '
72
+ class DateTimeParamType (click .ParamType ):
73
+ name = 'datetime '
75
74
76
75
def convert (self , value , param , ctx ):
77
76
if value :
78
- try :
79
- date = arrow .get (value )
80
- except (ValueError , TypeError ) as e :
81
- raise click .UsageError (str (e ))
77
+ date = self ._parse_multiformat (value )
78
+ if date is None :
79
+ raise click .UsageError (
80
+ "Could not match value '{}' to any supported date format"
81
+ .format (value )
82
+ )
82
83
# When we parse a date, we want to parse it in the timezone
83
84
# expected by the user, so that midnight is midnight in the local
84
85
# timezone, not in UTC. Cf issue #16.
@@ -92,34 +93,26 @@ def convert(self, value, param, ctx):
92
93
start_time = date , week_start = week_start )
93
94
return date
94
95
95
-
96
- class TimeParamType (click .ParamType ):
97
- name = 'time'
98
-
99
- def convert (self , value , param , ctx ):
100
- if isinstance (value , arrow .Arrow ):
101
- return value
102
-
103
- date_pattern = r'\d{4}-\d\d-\d\d'
104
- time_pattern = r'\d\d:\d\d(:\d\d)?'
105
-
106
- if re .match ('^{time_pat}$' .format (time_pat = time_pattern ), value ):
107
- cur_date = arrow .now ().date ().isoformat ()
108
- cur_time = '{date}T{time}' .format (date = cur_date , time = value )
109
- elif re .match ('^{date_pat}T{time_pat}' .format (
110
- date_pat = date_pattern , time_pat = time_pattern ), value ):
111
- cur_time = value
112
- else :
113
- errmsg = ('Could not parse time.'
114
- 'Please specify in (YYYY-MM-DDT)?HH:MM(:SS)? format.' )
115
- raise click .ClickException (style ('error' , errmsg ))
116
-
117
- local_tz = tz .tzlocal ()
118
- return arrow .get (cur_time ).replace (tzinfo = local_tz )
96
+ def _parse_multiformat (self , value ):
97
+ date = None
98
+ for fmt in (None , 'HH:mm:ss' , 'HH:mm' ):
99
+ try :
100
+ if fmt is None :
101
+ date = arrow .get (value )
102
+ else :
103
+ date = arrow .get (value , fmt )
104
+ date = arrow .now ().replace (
105
+ hour = date .hour ,
106
+ minute = date .minute ,
107
+ second = date .second
108
+ )
109
+ break
110
+ except (ValueError , TypeError ):
111
+ pass
112
+ return date
119
113
120
114
121
- Date = DateParamType ()
122
- Time = TimeParamType ()
115
+ DateTime = DateTimeParamType ()
123
116
124
117
125
118
def catch_watson_error (func ):
@@ -250,7 +243,7 @@ def start(ctx, watson, confirm_new_project, confirm_new_tag, args, gap_=True):
250
243
251
244
252
245
@cli .command (context_settings = {'ignore_unknown_options' : True })
253
- @click .option ('--at' , 'at_' , type = Time , default = None ,
246
+ @click .option ('--at' , 'at_' , type = DateTime , default = None ,
254
247
help = ('Stop frame at this time. Must be in '
255
248
'(YYYY-MM-DDT)?HH:MM(:SS)? format.' ))
256
249
@click .pass_obj
@@ -428,37 +421,37 @@ def status(watson, project, tags, elapsed):
428
421
@cli .command ()
429
422
@click .option ('-c/-C' , '--current/--no-current' , 'current' , default = None ,
430
423
help = "(Don't) include currently running frame in report." )
431
- @click .option ('-f' , '--from' , 'from_' , cls = MutuallyExclusiveOption , type = Date ,
432
- default = arrow .now ().shift (days = - 7 ),
424
+ @click .option ('-f' , '--from' , 'from_' , cls = MutuallyExclusiveOption ,
425
+ type = DateTime , default = arrow .now ().shift (days = - 7 ),
433
426
mutually_exclusive = _SHORTCUT_OPTIONS ,
434
427
help = "The date from when the report should start. Defaults "
435
428
"to seven days ago." )
436
- @click .option ('-t' , '--to' , cls = MutuallyExclusiveOption , type = Date ,
429
+ @click .option ('-t' , '--to' , cls = MutuallyExclusiveOption , type = DateTime ,
437
430
default = arrow .now (),
438
431
mutually_exclusive = _SHORTCUT_OPTIONS ,
439
432
help = "The date at which the report should stop (inclusive). "
440
433
"Defaults to tomorrow." )
441
- @click .option ('-y' , '--year' , cls = MutuallyExclusiveOption , type = Date ,
434
+ @click .option ('-y' , '--year' , cls = MutuallyExclusiveOption , type = DateTime ,
442
435
flag_value = _SHORTCUT_OPTIONS_VALUES ['year' ],
443
436
mutually_exclusive = ['day' , 'week' , 'luna' , 'month' , 'all' ],
444
437
help = 'Reports activity for the current year.' )
445
- @click .option ('-m' , '--month' , cls = MutuallyExclusiveOption , type = Date ,
438
+ @click .option ('-m' , '--month' , cls = MutuallyExclusiveOption , type = DateTime ,
446
439
flag_value = _SHORTCUT_OPTIONS_VALUES ['month' ],
447
440
mutually_exclusive = ['day' , 'week' , 'luna' , 'year' , 'all' ],
448
441
help = 'Reports activity for the current month.' )
449
- @click .option ('-l' , '--luna' , cls = MutuallyExclusiveOption , type = Date ,
442
+ @click .option ('-l' , '--luna' , cls = MutuallyExclusiveOption , type = DateTime ,
450
443
flag_value = _SHORTCUT_OPTIONS_VALUES ['luna' ],
451
444
mutually_exclusive = ['day' , 'week' , 'month' , 'year' , 'all' ],
452
445
help = 'Reports activity for the current moon cycle.' )
453
- @click .option ('-w' , '--week' , cls = MutuallyExclusiveOption , type = Date ,
446
+ @click .option ('-w' , '--week' , cls = MutuallyExclusiveOption , type = DateTime ,
454
447
flag_value = _SHORTCUT_OPTIONS_VALUES ['week' ],
455
448
mutually_exclusive = ['day' , 'month' , 'luna' , 'year' , 'all' ],
456
449
help = 'Reports activity for the current week.' )
457
- @click .option ('-d' , '--day' , cls = MutuallyExclusiveOption , type = Date ,
450
+ @click .option ('-d' , '--day' , cls = MutuallyExclusiveOption , type = DateTime ,
458
451
flag_value = _SHORTCUT_OPTIONS_VALUES ['day' ],
459
452
mutually_exclusive = ['week' , 'month' , 'luna' , 'year' , 'all' ],
460
453
help = 'Reports activity for the current day.' )
461
- @click .option ('-a' , '--all' , cls = MutuallyExclusiveOption , type = Date ,
454
+ @click .option ('-a' , '--all' , cls = MutuallyExclusiveOption , type = DateTime ,
462
455
flag_value = _SHORTCUT_OPTIONS_VALUES ['all' ],
463
456
mutually_exclusive = ['day' , 'week' , 'month' , 'luna' , 'year' ],
464
457
help = 'Reports all activities.' )
@@ -717,12 +710,12 @@ def _final_print(lines):
717
710
@cli .command ()
718
711
@click .option ('-c/-C' , '--current/--no-current' , 'current' , default = None ,
719
712
help = "(Don't) include currently running frame in report." )
720
- @click .option ('-f' , '--from' , 'from_' , cls = MutuallyExclusiveOption , type = Date ,
721
- default = arrow .now ().shift (days = - 7 ),
713
+ @click .option ('-f' , '--from' , 'from_' , cls = MutuallyExclusiveOption ,
714
+ type = DateTime , default = arrow .now ().shift (days = - 7 ),
722
715
mutually_exclusive = _SHORTCUT_OPTIONS ,
723
716
help = "The date from when the report should start. Defaults "
724
717
"to seven days ago." )
725
- @click .option ('-t' , '--to' , cls = MutuallyExclusiveOption , type = Date ,
718
+ @click .option ('-t' , '--to' , cls = MutuallyExclusiveOption , type = DateTime ,
726
719
default = arrow .now (),
727
720
mutually_exclusive = _SHORTCUT_OPTIONS ,
728
721
help = "The date at which the report should stop (inclusive). "
@@ -861,34 +854,34 @@ def aggregate(ctx, watson, current, from_, to, projects, tags, output_format,
861
854
@cli .command ()
862
855
@click .option ('-c/-C' , '--current/--no-current' , 'current' , default = None ,
863
856
help = "(Don't) include currently running frame in output." )
864
- @click .option ('-f' , '--from' , 'from_' , type = Date ,
857
+ @click .option ('-f' , '--from' , 'from_' , type = DateTime ,
865
858
default = arrow .now ().shift (days = - 7 ),
866
859
help = "The date from when the log should start. Defaults "
867
860
"to seven days ago." )
868
- @click .option ('-t' , '--to' , type = Date , default = arrow .now (),
861
+ @click .option ('-t' , '--to' , type = DateTime , default = arrow .now (),
869
862
help = "The date at which the log should stop (inclusive). "
870
863
"Defaults to tomorrow." )
871
- @click .option ('-y' , '--year' , cls = MutuallyExclusiveOption , type = Date ,
864
+ @click .option ('-y' , '--year' , cls = MutuallyExclusiveOption , type = DateTime ,
872
865
flag_value = _SHORTCUT_OPTIONS_VALUES ['year' ],
873
866
mutually_exclusive = ['day' , 'week' , 'month' , 'all' ],
874
867
help = 'Reports activity for the current year.' )
875
- @click .option ('-m' , '--month' , cls = MutuallyExclusiveOption , type = Date ,
868
+ @click .option ('-m' , '--month' , cls = MutuallyExclusiveOption , type = DateTime ,
876
869
flag_value = _SHORTCUT_OPTIONS_VALUES ['month' ],
877
870
mutually_exclusive = ['day' , 'week' , 'year' , 'all' ],
878
871
help = 'Reports activity for the current month.' )
879
- @click .option ('-l' , '--luna' , cls = MutuallyExclusiveOption , type = Date ,
872
+ @click .option ('-l' , '--luna' , cls = MutuallyExclusiveOption , type = DateTime ,
880
873
flag_value = _SHORTCUT_OPTIONS_VALUES ['luna' ],
881
874
mutually_exclusive = ['day' , 'week' , 'month' , 'year' , 'all' ],
882
875
help = 'Reports activity for the current moon cycle.' )
883
- @click .option ('-w' , '--week' , cls = MutuallyExclusiveOption , type = Date ,
876
+ @click .option ('-w' , '--week' , cls = MutuallyExclusiveOption , type = DateTime ,
884
877
flag_value = _SHORTCUT_OPTIONS_VALUES ['week' ],
885
878
mutually_exclusive = ['day' , 'month' , 'year' , 'all' ],
886
879
help = 'Reports activity for the current week.' )
887
- @click .option ('-d' , '--day' , cls = MutuallyExclusiveOption , type = Date ,
880
+ @click .option ('-d' , '--day' , cls = MutuallyExclusiveOption , type = DateTime ,
888
881
flag_value = _SHORTCUT_OPTIONS_VALUES ['day' ],
889
882
mutually_exclusive = ['week' , 'month' , 'year' , 'all' ],
890
883
help = 'Reports activity for the current day.' )
891
- @click .option ('-a' , '--all' , cls = MutuallyExclusiveOption , type = Date ,
884
+ @click .option ('-a' , '--all' , cls = MutuallyExclusiveOption , type = DateTime ,
892
885
flag_value = _SHORTCUT_OPTIONS_VALUES ['all' ],
893
886
mutually_exclusive = ['day' , 'week' , 'month' , 'year' ],
894
887
help = 'Reports all activities.' )
@@ -1138,9 +1131,9 @@ def frames(watson):
1138
1131
@cli .command (context_settings = {'ignore_unknown_options' : True })
1139
1132
@click .argument ('args' , nargs = - 1 ,
1140
1133
autocompletion = get_project_or_task_completion )
1141
- @click .option ('-f' , '--from' , 'from_' , required = True , type = Date ,
1134
+ @click .option ('-f' , '--from' , 'from_' , required = True , type = DateTime ,
1142
1135
help = "Date and time of start of tracked activity" )
1143
- @click .option ('-t' , '--to' , required = True , type = Date ,
1136
+ @click .option ('-t' , '--to' , required = True , type = DateTime ,
1144
1137
help = "Date and time of end of tracked activity" )
1145
1138
@click .option ('-c' , '--confirm-new-project' , is_flag = True , default = False ,
1146
1139
help = "Confirm addition of new project." )
0 commit comments