mirror of
				https://git.webmeisterei.com/webmeisterei/todoist-taskwarrior.git
				synced 2025-10-31 02:02:41 +01:00 
			
		
		
		
	Support every *other* DOW and ignore timestamps in recurrences (e.g. every other day at 9:00)
This commit is contained in:
		| @@ -25,6 +25,9 @@ def test_every_n_days(): | ||||
|     assert utils.parse_recur('every 3 day') == '3 days' | ||||
|     assert utils.parse_recur('every 3 days') == '3 days' | ||||
|  | ||||
|     # With time (which should be ignored since it's encoded in due_date anyways) | ||||
|     assert utils.parse_recur('every day at 19:00') == 'daily' | ||||
|  | ||||
|  | ||||
| def test_special(): | ||||
|     # Indicates daily at 9am - the time is saved in the `due` property | ||||
| @@ -42,6 +45,7 @@ def test_weekly(): | ||||
|     assert utils.parse_recur('every 1 week') == 'weekly' | ||||
|     assert utils.parse_recur('every 1 weeks') == 'weekly' | ||||
|     assert utils.parse_recur('weekly') == 'weekly' | ||||
|     assert utils.parse_recur('every other week') == '2 weeks' | ||||
|     assert utils.parse_recur('every 3 week') == '3 weeks' | ||||
|     assert utils.parse_recur('every 3 weeks') == '3 weeks' | ||||
|  | ||||
| @@ -51,12 +55,14 @@ def test_monthly(): | ||||
|     assert utils.parse_recur('every 1 month') == 'monthly' | ||||
|     assert utils.parse_recur('every 1 months') == 'monthly' | ||||
|     assert utils.parse_recur('monthly') == 'monthly' | ||||
|     assert utils.parse_recur('every other month') == '2 months' | ||||
|     assert utils.parse_recur('every 2 months') == '2 months' | ||||
|  | ||||
|     # ordinal | ||||
|     assert utils.parse_recur('every 2nd month') == '2 months' | ||||
|     assert utils.parse_recur('every 3rd month') == '3 months' | ||||
|  | ||||
|  | ||||
| DAYS_OF_WEEK = [ | ||||
|     # Monday | ||||
|     'mo', | ||||
| @@ -105,7 +111,10 @@ def test_every_dow_has_weekly_recurrence(dow): | ||||
|     """ | ||||
|     assert utils.parse_recur(f'ev {dow}') == 'weekly' | ||||
|     assert utils.parse_recur(f'every {dow}') == 'weekly' | ||||
|     assert utils.parse_recur(f'every other {dow}') == '2 weeks' | ||||
|  | ||||
|     # With time (which should be ignored since it's encoded in due_date anyways) | ||||
|     assert utils.parse_recur(f'every {dow} at 17:00') == 'weekly' | ||||
|  | ||||
| @pytest.mark.parametrize('ordinal', [ | ||||
|     ('2', 2), | ||||
|   | ||||
| @@ -103,6 +103,7 @@ def parse_recur(date_string): | ||||
| _PERIOD = r'(?P<period>hour|day|week|month|year)s?' | ||||
| _EVERY = r'ev(ery)?' | ||||
| _CYCLES = r'((?P<cycles>\d+)(st|nd|rd|th)?)' | ||||
| _OTHER  = r'(?P<other>other)' | ||||
| _SIMPLE = r'(?P<simple>daily|weekly|monthly|yearly)' | ||||
| _DOW = ( | ||||
|     r'((?P<dayofweek>(' | ||||
| @@ -114,18 +115,19 @@ _DOW = ( | ||||
|     r'|su(n(day)?)?' | ||||
|     r')))' | ||||
| ) | ||||
| _IGNORED = r'(\sat (\d{1,2}:\d{1,2})|(\d{1,2}(am|pm)))?' | ||||
|  | ||||
| # A single cycle recurrence is one of: | ||||
| # - daily, weekly, monthly, yearly | ||||
| # - every day, every week, every month, every year | ||||
| # - every 1 day, every 1 week, every 1 month, every 1 year | ||||
| RE_SINGLE_CYCLE = re.compile( | ||||
|     fr'^(({_EVERY}\s(1\s)?{_PERIOD})|{_SIMPLE})$' | ||||
|     fr'^(({_EVERY}\s(1\s)?{_PERIOD})|{_SIMPLE}){_IGNORED}$' | ||||
| ) | ||||
|  | ||||
| # A multi cycle recurrence is of the form: every N <period>s | ||||
| RE_MULTI_CYCLE = re.compile( | ||||
|     fr'^{_EVERY}\s({_CYCLES}|other)\s{_PERIOD}$' | ||||
|     fr'^{_EVERY}\s({_CYCLES}|other)\s{_PERIOD}{_IGNORED}$' | ||||
| ) | ||||
|  | ||||
|  | ||||
| @@ -133,13 +135,13 @@ RE_MULTI_CYCLE = re.compile( | ||||
| # - every (monday | tuesday | ...) | ||||
| # - every Nth (monday | tuesday | ...) | ||||
| RE_EVERY_DOW = re.compile( | ||||
|     fr'^{_EVERY}\s({_CYCLES}\s)?{_DOW}$' | ||||
|     fr'^{_EVERY}\s(({_CYCLES}|{_OTHER})\s)?{_DOW}{_IGNORED}$' | ||||
| ) | ||||
|  | ||||
|  | ||||
| # A day of month recurrence is of the form: every Nth | ||||
| RE_EVERY_DOM = re.compile( | ||||
|     fr'^{_EVERY}\s{_CYCLES}$' | ||||
|     fr'^{_EVERY}\s{_CYCLES}{_IGNORED}$' | ||||
| ) | ||||
|  | ||||
|  | ||||
| @@ -194,10 +196,14 @@ def _recur_day_of_week(date_string): | ||||
|  | ||||
|     groups = match.groupdict() | ||||
|     day_of_week = groups['dayofweek'] | ||||
|  | ||||
|     if groups['cycles']: | ||||
|         cycles = groups['cycles'] | ||||
|     elif groups['other']: | ||||
|         cycles = 2 | ||||
|     else: | ||||
|         cycles = 1 | ||||
|  | ||||
|     return 'weekly' if cycles == 1 else f'{cycles} weeks' | ||||
|  | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Matt Snider
					Matt Snider