Update to todoist-python 8.0.0

This commit is contained in:
Matt Snider 2019-07-13 13:33:17 +02:00
parent d2cd7b2b4a
commit 81ee6d16dc
5 changed files with 120 additions and 80 deletions

View File

@ -1,5 +1,5 @@
Click==7.0
todoist-python==7.0.18
todoist-python==8.0.0
# Temporarily use this until upstream PR #121 is merged
# https://github.com/ralphbean/taskw/pull/121

View File

@ -7,60 +7,68 @@ from todoist_taskwarrior import utils
from todoist_taskwarrior import errors
def test_parse_due_object():
assert utils.parse_recur(None) == None
assert utils.parse_recur({'is_recurring': False}) == None
assert utils.parse_recur({'is_recurring': True, 'string': 'every day'}) == 'daily'
assert utils.parse_recur({'is_recurring': True, 'string': 'every week'}) == 'weekly'
assert utils.parse_recur({'is_recurring': True, 'string': 'every month'}) == 'monthly'
def test_hourly():
assert utils.parse_recur('every hour') == 'hourly'
assert utils.parse_recur('every 1 hour') == 'hourly'
assert utils.parse_recur('every 2 hour') == '2 hours'
assert utils.parse_recur('every 2 hours') == '2 hours'
assert utils.parse_recur('every 3 hour') == '3 hours'
assert utils.parse_recur('every 3 hours') == '3 hours'
assert utils.parse_recur_string('every hour') == 'hourly'
assert utils.parse_recur_string('every 1 hour') == 'hourly'
assert utils.parse_recur_string('every 2 hour') == '2 hours'
assert utils.parse_recur_string('every 2 hours') == '2 hours'
assert utils.parse_recur_string('every 3 hour') == '3 hours'
assert utils.parse_recur_string('every 3 hours') == '3 hours'
def test_every_n_days():
assert utils.parse_recur('daily') == 'daily'
assert utils.parse_recur('every day') == 'daily'
assert utils.parse_recur('every 1 day') == 'daily'
assert utils.parse_recur('every 1 days') == 'daily'
assert utils.parse_recur('every other day') == '2 days'
assert utils.parse_recur('every 3 day') == '3 days'
assert utils.parse_recur('every 3 days') == '3 days'
assert utils.parse_recur_string('daily') == 'daily'
assert utils.parse_recur_string('every day') == 'daily'
assert utils.parse_recur_string('every 1 day') == 'daily'
assert utils.parse_recur_string('every 1 days') == 'daily'
assert utils.parse_recur_string('every other day') == '2 days'
assert utils.parse_recur_string('every 3 day') == '3 days'
assert utils.parse_recur_string('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'
assert utils.parse_recur_string('every day at 19:00') == 'daily'
def test_special():
# Indicates daily at 9am - the time is saved in the `due` property
assert utils.parse_recur('every morning') == 'daily'
assert utils.parse_recur_string('every morning') == 'daily'
# Indicates daily at 7pm - the time is saved in the `due` property
assert utils.parse_recur('every evening') == 'daily'
assert utils.parse_recur_string('every evening') == 'daily'
# Weekdays
assert utils.parse_recur('every weekday') == 'weekdays'
assert utils.parse_recur('every workday') == 'weekdays'
assert utils.parse_recur_string('every weekday') == 'weekdays'
assert utils.parse_recur_string('every workday') == 'weekdays'
def test_weekly():
assert utils.parse_recur('every week') == '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'
assert utils.parse_recur_string('every week') == 'weekly'
assert utils.parse_recur_string('every 1 week') == 'weekly'
assert utils.parse_recur_string('every 1 weeks') == 'weekly'
assert utils.parse_recur_string('weekly') == 'weekly'
assert utils.parse_recur_string('every other week') == '2 weeks'
assert utils.parse_recur_string('every 3 week') == '3 weeks'
assert utils.parse_recur_string('every 3 weeks') == '3 weeks'
def test_monthly():
assert utils.parse_recur('every month') == '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'
assert utils.parse_recur_string('every month') == 'monthly'
assert utils.parse_recur_string('every 1 month') == 'monthly'
assert utils.parse_recur_string('every 1 months') == 'monthly'
assert utils.parse_recur_string('monthly') == 'monthly'
assert utils.parse_recur_string('every other month') == '2 months'
assert utils.parse_recur_string('every 2 months') == '2 months'
# ordinal
assert utils.parse_recur('every 2nd month') == '2 months'
assert utils.parse_recur('every 3rd month') == '3 months'
assert utils.parse_recur_string('every 2nd month') == '2 months'
assert utils.parse_recur_string('every 3rd month') == '3 months'
DAYS_OF_WEEK = [
@ -109,12 +117,12 @@ def test_every_dow_has_weekly_recurrence(dow):
""" The actual day should be indicated in the `due` property, so here
we just need to ensure that the recurrence is correct.
"""
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'
assert utils.parse_recur_string(f'ev {dow}') == 'weekly'
assert utils.parse_recur_string(f'every {dow}') == 'weekly'
assert utils.parse_recur_string(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'
assert utils.parse_recur_string(f'every {dow} at 17:00') == 'weekly'
@pytest.mark.parametrize('ordinal', [
('2', 2),
@ -127,61 +135,61 @@ def test_every_dow_has_weekly_recurrence(dow):
@pytest.mark.parametrize('dow', DAYS_OF_WEEK)
def test_every_dow_ordinal_recurrence(ordinal, dow):
ordinal, expected = ordinal
assert utils.parse_recur(f'ev {ordinal} {dow}') == f'{expected} weeks'
assert utils.parse_recur(f'every {ordinal} {dow}') == f'{expected} weeks'
assert utils.parse_recur_string(f'ev {ordinal} {dow}') == f'{expected} weeks'
assert utils.parse_recur_string(f'every {ordinal} {dow}') == f'{expected} weeks'
def test_day_of_week_short_forms():
assert utils.parse_recur('every mo') == 'weekly'
assert utils.parse_recur('every mon') == 'weekly'
assert utils.parse_recur_string('every mo') == 'weekly'
assert utils.parse_recur_string('every mon') == 'weekly'
assert utils.parse_recur('every tu') == 'weekly'
assert utils.parse_recur('every tue') == 'weekly'
assert utils.parse_recur('every tues') == 'weekly'
assert utils.parse_recur_string('every tu') == 'weekly'
assert utils.parse_recur_string('every tue') == 'weekly'
assert utils.parse_recur_string('every tues') == 'weekly'
assert utils.parse_recur('every we') == 'weekly'
assert utils.parse_recur('every wed') == 'weekly'
assert utils.parse_recur('every weds') == 'weekly'
assert utils.parse_recur_string('every we') == 'weekly'
assert utils.parse_recur_string('every wed') == 'weekly'
assert utils.parse_recur_string('every weds') == 'weekly'
assert utils.parse_recur('every th') == 'weekly'
assert utils.parse_recur('every thu') == 'weekly'
assert utils.parse_recur('every thurs') == 'weekly'
assert utils.parse_recur_string('every th') == 'weekly'
assert utils.parse_recur_string('every thu') == 'weekly'
assert utils.parse_recur_string('every thurs') == 'weekly'
assert utils.parse_recur('every fr') == 'weekly'
assert utils.parse_recur('every fri') == 'weekly'
assert utils.parse_recur_string('every fr') == 'weekly'
assert utils.parse_recur_string('every fri') == 'weekly'
assert utils.parse_recur('every sa') == 'weekly'
assert utils.parse_recur('every sat') == 'weekly'
assert utils.parse_recur_string('every sa') == 'weekly'
assert utils.parse_recur_string('every sat') == 'weekly'
assert utils.parse_recur('every su') == 'weekly'
assert utils.parse_recur('every sun') == 'weekly'
assert utils.parse_recur_string('every su') == 'weekly'
assert utils.parse_recur_string('every sun') == 'weekly'
def test_day_of_month():
""" The actual due date should be indicated by the `due` property, so here
we just need to ensure a monthly recurrence.
"""
assert utils.parse_recur('every 1st') == 'monthly'
assert utils.parse_recur('every 2nd') == 'monthly'
assert utils.parse_recur('every 3rd') == 'monthly'
assert utils.parse_recur('every 4th') == 'monthly'
assert utils.parse_recur('every 21st') == 'monthly'
assert utils.parse_recur('every 22nd') == 'monthly'
assert utils.parse_recur('every 23rd') == 'monthly'
assert utils.parse_recur('every 24th') == 'monthly'
assert utils.parse_recur('every last day') == 'monthly'
assert utils.parse_recur_string('every 1st') == 'monthly'
assert utils.parse_recur_string('every 2nd') == 'monthly'
assert utils.parse_recur_string('every 3rd') == 'monthly'
assert utils.parse_recur_string('every 4th') == 'monthly'
assert utils.parse_recur_string('every 21st') == 'monthly'
assert utils.parse_recur_string('every 22nd') == 'monthly'
assert utils.parse_recur_string('every 23rd') == 'monthly'
assert utils.parse_recur_string('every 24th') == 'monthly'
assert utils.parse_recur_string('every last day') == 'monthly'
def test_annually():
assert utils.parse_recur('every year') == 'yearly'
assert utils.parse_recur('every 2 year') == '2 years'
assert utils.parse_recur('every 2 years') == '2 years'
assert utils.parse_recur_string('every year') == 'yearly'
assert utils.parse_recur_string('every 2 year') == '2 years'
assert utils.parse_recur_string('every 2 years') == '2 years'
def test_unsupported():
with pytest.raises(errors.UnsupportedRecurrence):
utils.parse_recur('every mon,tues,weds')
utils.parse_recur_string('every mon,tues,weds')
with pytest.raises(errors.UnsupportedRecurrence):
utils.parse_recur('every monday,tuesday,wednesday')
utils.parse_recur_string('every monday,tuesday,wednesday')

View File

@ -146,8 +146,8 @@ def migrate(ctx, interactive, sync, map_project, map_tag):
# Dates
data['entry'] = utils.parse_date(task['date_added'])
data['due'] = utils.parse_date(task['due_date_utc'])
data['recur'] = parse_recur_or_prompt(task['date_string'])
data['due'] = utils.parse_due(utils.try_get_model_prop(task, 'due'))
data['recur'] = parse_recur_or_prompt(utils.try_get_model_prop(task, 'due'))
if not interactive:
add_task(**data)
@ -279,11 +279,11 @@ def add_task_interactive(**task_data):
return add_task(**task_data)
def parse_recur_or_prompt(value):
def parse_recur_or_prompt(due):
try:
return utils.parse_recur(value)
return utils.parse_recur(due)
except errors.UnsupportedRecurrence:
io.error('Unsupported recurrence: %s. Please enter a valid value' % value)
io.error("Unsupported recurrence: '%s'. Please enter a valid value" % due['string'])
return io.prompt(
'Set recurrence (todoist style)',
default='',

View File

@ -1,6 +1,6 @@
import click
import re
from datetime import datetime
import dateutil.parser
from .errors import UnsupportedRecurrence
@ -14,6 +14,14 @@ def try_map(m, value):
return value
def try_get_model_prop(m, key, default=None):
""" The todoist models don't seem to have the `get()` method and throw KeyErrors """
try:
return m[key]
except KeyError:
return default
""" Priorities """
PRIORITY_MAP = {1: None, 2: 'L', 3: 'M', 4: 'H'}
@ -38,6 +46,23 @@ def maybe_quote_ws(value):
""" Dates """
def parse_due(due):
"""Parse a due date from the due object.
e.g. {
"date": "2016-12-0T12:00:00",
"timezone": null,
"string": "every day at 12",
"lang": "en",
"is_recurring": true
}
"""
if not due:
return None
return parse_date(due['date'])
def parse_date(date):
""" Converts a date from Todoist to Taskwarrior.
@ -47,10 +72,17 @@ def parse_date(date):
if not date:
return None
return datetime.strptime(date, '%a %d %b %Y %H:%M:%S %z').isoformat()
return dateutil.parser.parse(date).isoformat()
def parse_recur(date_string):
def parse_recur(due):
"""Given a due object, extracts the recur """
if not due or not due['is_recurring']:
return None
return parse_recur_string(due['string'])
def parse_recur_string(date_string):
""" Parses a Todoist `date_string` to extract a `recur` string for Taskwarrior.
Field:

View File

@ -18,6 +18,6 @@ def validate_map(ctx, param, value):
def validate_recur(value):
try:
return utils.parse_recur(value)
return utils.parse_recur_string(value)
except errors.UnsupportedRecurrence as e:
raise click.BadParameter(e)