Skip to content
This repository has been archived by the owner on Feb 21, 2022. It is now read-only.

Commit

Permalink
Migrate to the v7 API.
Browse files Browse the repository at this point in the history
  • Loading branch information
lefcha committed Jun 5, 2016
1 parent 9656a75 commit bd2d025
Show file tree
Hide file tree
Showing 13 changed files with 303 additions and 310 deletions.
418 changes: 209 additions & 209 deletions tests/test_api.py

Large diffs are not rendered by default.

169 changes: 81 additions & 88 deletions todoist/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,26 +67,24 @@ def __init__(self, token='', api_endpoint='https://api.todoist.com', session=Non
def reset_state(self):
self.sync_token = '*'
self.state = { # Local copy of all of the user's objects
'CollaboratorStates': [],
'Collaborators': [],
'DayOrders': {},
'DayOrdersTimestamp': '',
'Filters': [],
'Items': [],
'Labels': [],
'LiveNotifications': [],
'LiveNotificationsLastRead': -1,
'LiveNotificationsLastReadId': -1,
'Locations': [],
'Notes': [],
'ProjectNotes': [],
'Projects': [],
'Reminders': [],
'Settings': {},
'SettingsNotifications': {},
'User': {},
'UserId': -1,
'WebStaticVersion': -1,
'collaborator_states': [],
'collaborators': [],
'day_orders': {},
'day_orders_timestamp': '',
'filters': [],
'items': [],
'labels': [],
'live_notifications': [],
'live_notifications_last_read_id': -1,
'locations': [],
'notes': [],
'project_notes': [],
'projects': [],
'reminders': [],
'settings': {},
'settings_notifications': {},
'user': {},
'web_static_version': -1,
}

def __getitem__(self, key):
Expand All @@ -96,7 +94,7 @@ def serialize(self):
return {key: getattr(self, key) for key in self._serialize_fields}

def get_api_url(self):
return '%s/API/v6/' % self.api_endpoint
return '%s/API/v7/' % self.api_endpoint

def _update_state(self, syncdata):
"""
Expand All @@ -109,47 +107,42 @@ def _update_state(self, syncdata):
# It is straightforward to update these type of data, since it is
# enough to just see if they are present in the sync data, and then
# either replace the local values or update them.
if 'Collaborators' in syncdata:
self.state['Collaborators'] = syncdata['Collaborators']
if 'CollaboratorStates' in syncdata:
self.state['CollaboratorStates'] = syncdata['CollaboratorStates']
if 'DayOrders' in syncdata:
self.state['DayOrders'].update(syncdata['DayOrders'])
if 'DayOrdersTimestamp' in syncdata:
self.state['DayOrdersTimestamp'] = syncdata['DayOrdersTimestamp']
if 'LiveNotificationsLastRead' in syncdata:
self.state['LiveNotificationsLastRead'] = \
syncdata['LiveNotificationsLastRead']
if 'LiveNotificationsLastReadId' in syncdata:
self.state['LiveNotificationsLastReadId'] = \
syncdata['LiveNotificationsLastReadId']
if 'Locations' in syncdata:
self.state['Locations'] = syncdata['Locations']
if 'Settings' in syncdata:
self.state['Settings'].update(syncdata['Settings'])
if 'SettingsNotifications' in syncdata:
self.state['SettingsNotifications'].\
update(syncdata['SettingsNotifications'])
if 'User' in syncdata:
self.state['User'].update(syncdata['User'])
if 'UserId' in syncdata:
self.state['UserId'] = syncdata['UserId']
if 'WebStaticVersion' in syncdata:
self.state['WebStaticVersion'] = syncdata['WebStaticVersion']
if 'collaborators' in syncdata:
self.state['collaborators'] = syncdata['collaborators']
if 'collaborator_states' in syncdata:
self.state['collaborator_states'] = syncdata['collaborator_states']
if 'day_orders' in syncdata:
self.state['day_orders'].update(syncdata['day_orders'])
if 'day_orders_timestamp' in syncdata:
self.state['day_orders_timestamp'] = syncdata['day_orders_timestamp']
if 'live_notifications_last_read_id' in syncdata:
self.state['live_notifications_last_read_id'] = \
syncdata['live_notifications_last_read_id']
if 'locations' in syncdata:
self.state['locations'] = syncdata['locations']
if 'settings' in syncdata:
self.state['settings'].update(syncdata['settings'])
if 'settings_notifications' in syncdata:
self.state['settings_notifications'].\
update(syncdata['settings_notifications'])
if 'user' in syncdata:
self.state['user'].update(syncdata['user'])
if 'web_static_version' in syncdata:
self.state['web_static_version'] = syncdata['web_static_version']

# Updating these type of data is a bit more complicated, since it is
# necessary to find out whether an object in the sync data is new,
# updates an existing object, or marks an object to be deleted. But
# the same procedure takes place for each of these types of data.
resp_models_mapping = [
('Filters', models.Filter),
('Items', models.Item),
('Labels', models.Label),
('LiveNotifications', models.LiveNotification),
('Notes', models.Note),
('ProjectNotes', models.ProjectNote),
('Projects', models.Project),
('Reminders', models.Reminder),
('filters', models.Filter),
('items', models.Item),
('labels', models.Label),
('live_notifications', models.LiveNotification),
('notes', models.Note),
('project_notes', models.ProjectNote),
('projects', models.Project),
('reminders', models.Reminder),
]
for datatype, model in resp_models_mapping:
if datatype not in syncdata:
Expand Down Expand Up @@ -182,26 +175,26 @@ def _find_object(self, objtype, obj):
object, and then on its primary key is. If the object is found it is
returned, and if not, then None is returned.
"""
if objtype == 'Collaborators':
if objtype == 'collaborators':
return self.collaborators.get_by_id(obj['id'])
elif objtype == 'CollaboratorStates':
elif objtype == 'collaborator_states':
return self.collaborator_states.get_by_ids(obj['project_id'],
obj['user_id'])
elif objtype == 'Filters':
elif objtype == 'filters':
return self.filters.get_by_id(obj['id'], only_local=True)
elif objtype == 'Items':
elif objtype == 'items':
return self.items.get_by_id(obj['id'], only_local=True)
elif objtype == 'Labels':
elif objtype == 'labels':
return self.labels.get_by_id(obj['id'], only_local=True)
elif objtype == 'LiveNotifications':
elif objtype == 'live_notifications':
return self.live_notifications.get_by_key(obj['notification_key'])
elif objtype == 'Notes':
elif objtype == 'notes':
return self.notes.get_by_id(obj['id'], only_local=True)
elif objtype == 'ProjectNotes':
elif objtype == 'project_notes':
return self.project_notes.get_by_id(obj['id'], only_local=True)
elif objtype == 'Projects':
elif objtype == 'projects':
return self.projects.get_by_id(obj['id'], only_local=True)
elif objtype == 'Reminders':
elif objtype == 'reminders':
return self.reminders.get_by_id(obj['id'], only_local=True)
else:
return None
Expand All @@ -214,8 +207,8 @@ def _replace_temp_id(self, temp_id, new_id):
"""
# Go through all the objects for which we expect the temporary id to be
# replaced by a real one.
for datatype in ['Filters', 'Items', 'Labels', 'Notes', 'ProjectNotes',
'Projects', 'Reminders']:
for datatype in ['filters', 'items', 'labels', 'notes', 'project_notes',
'projects', 'reminders']:
for obj in self.state[datatype]:
if obj.temp_id == temp_id:
obj['id'] = new_id
Expand Down Expand Up @@ -268,14 +261,14 @@ def sync(self, commands=None):
post_data = {
'token': self.token,
'sync_token': self.sync_token,
'day_orders_timestamp': self.state['DayOrdersTimestamp'],
'day_orders_timestamp': self.state['day_orders_timestamp'],
'include_notification_settings': 1,
'resource_types': json_dumps(['all']),
'commands': json_dumps(commands or []),
}
response = self._post('sync', data=post_data)
if 'TempIdMapping' in response:
for temp_id, new_id in response['TempIdMapping'].items():
if 'temp_id_mapping' in response:
for temp_id, new_id in response['temp_id_mapping'].items():
self.temp_ids[temp_id] = new_id
self._replace_temp_id(temp_id, new_id)
self._update_state(response)
Expand All @@ -292,9 +285,9 @@ def commit(self, raise_on_error=True):
return
ret = self.sync(commands=self.queue)
del self.queue[:]
if 'SyncStatus' in ret:
if 'sync_status' in ret:
if raise_on_error:
for k, v in ret['SyncStatus'].items():
for k, v in ret['sync_status'].items():
if v != 'ok':
raise SyncError(k, v)
return ret
Expand Down Expand Up @@ -492,11 +485,11 @@ def get_project(self, project_id):
obj = self._get('get_project', params=params)
if obj and 'error' in obj:
return None
data = {'Projects': [], 'ProjectNotes': []}
data = {'projects': [], 'project_notes': []}
if obj.get('project'):
data['Projects'].append(obj.get('project'))
data['projects'].append(obj.get('project'))
if obj.get('notes'):
data['ProjectNotes'] += obj.get('notes')
data['project_notes'] += obj.get('notes')
self._update_state(data)
return obj

Expand All @@ -509,13 +502,13 @@ def get_item(self, item_id):
obj = self._get('get_item', params=params)
if obj and 'error' in obj:
return None
data = {'Projects': [], 'Items': [], 'Notes': []}
data = {'projects': [], 'items': [], 'notes': []}
if obj.get('project'):
data['Projects'].append(obj.get('project'))
data['projects'].append(obj.get('project'))
if obj.get('item'):
data['Items'].append(obj.get('item'))
data['items'].append(obj.get('item'))
if obj.get('notes'):
data['Notes'] += obj.get('notes')
data['notes'] += obj.get('notes')
self._update_state(data)
return obj

Expand All @@ -528,9 +521,9 @@ def get_label(self, label_id):
obj = self._get('get_label', params=params)
if obj and 'error' in obj:
return None
data = {'Labels': []}
data = {'labels': []}
if obj.get('label'):
data['Labels'].append(obj.get('label'))
data['labels'].append(obj.get('label'))
self._update_state(data)
return obj

Expand All @@ -543,9 +536,9 @@ def get_note(self, note_id):
obj = self._get('get_note', params=params)
if obj and 'error' in obj:
return None
data = {'Notes': []}
data = {'notes': []}
if obj.get('note'):
data['Notes'].append(obj.get('note'))
data['notes'].append(obj.get('note'))
self._update_state(data)
return obj

Expand All @@ -558,9 +551,9 @@ def get_filter(self, filter_id):
obj = self._get('get_filter', params=params)
if obj and 'error' in obj:
return None
data = {'Filters': []}
data = {'filters': []}
if obj.get('filter'):
data['Filters'].append(obj.get('filter'))
data['filters'].append(obj.get('filter'))
self._update_state(data)
return obj

Expand All @@ -573,9 +566,9 @@ def get_reminder(self, reminder_id):
obj = self._get('get_reminder', params=params)
if obj and 'error' in obj:
return None
data = {'Reminders': []}
data = {'reminders': []}
if obj.get('reminder'):
data['Reminders'].append(obj.get('reminder'))
data['reminders'].append(obj.get('reminder'))
self._update_state(data)
return obj

Expand Down
2 changes: 1 addition & 1 deletion todoist/managers/collaborator_states.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

class CollaboratorStatesManager(Manager, SyncMixin):

state_name = 'CollaboratorStates'
state_name = 'collaborator_states'
object_type = None # there is no object type associated

def get_by_ids(self, project_id, user_id):
Expand Down
2 changes: 1 addition & 1 deletion todoist/managers/collaborators.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

class CollaboratorsManager(Manager, GetByIdMixin, SyncMixin):

state_name = 'Collaborators'
state_name = 'collaborators'
object_type = None # there is no object type associated

def get_by_id(self, user_id):
Expand Down
2 changes: 1 addition & 1 deletion todoist/managers/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

class FiltersManager(Manager, AllMixin, GetByIdMixin, SyncMixin):

state_name = 'Filters'
state_name = 'filters'
object_type = 'filter'

def add(self, name, query, **kwargs):
Expand Down
2 changes: 1 addition & 1 deletion todoist/managers/items.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

class ItemsManager(Manager, AllMixin, GetByIdMixin, SyncMixin):

state_name = 'Items'
state_name = 'items'
object_type = 'item'

def add(self, content, project_id, **kwargs):
Expand Down
2 changes: 1 addition & 1 deletion todoist/managers/labels.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

class LabelsManager(Manager, AllMixin, GetByIdMixin, SyncMixin):

state_name = 'Labels'
state_name = 'labels'
object_type = 'label'

def add(self, name, **kwargs):
Expand Down
2 changes: 1 addition & 1 deletion todoist/managers/live_notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

class LiveNotificationsManager(Manager, AllMixin, SyncMixin):

state_name = 'LiveNotifications'
state_name = 'live_notifications'
object_type = 'live_notification'

def get_by_key(self, notification_key):
Expand Down
2 changes: 1 addition & 1 deletion todoist/managers/locations.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

class LocationsManager(Manager, AllMixin, SyncMixin):

state_name = 'Locations'
state_name = 'locations'
object_type = None # there is no local state associated

def clear(self):
Expand Down
4 changes: 2 additions & 2 deletions todoist/managers/notes.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def delete(self, note_id):

class NotesManager(GenericNotesManager):

state_name = 'Notes'
state_name = 'notes'

def add(self, item_id, content, **kwargs):
"""
Expand All @@ -61,7 +61,7 @@ def add(self, item_id, content, **kwargs):

class ProjectNotesManager(GenericNotesManager):

state_name = 'ProjectNotes'
state_name = 'project_notes'

def add(self, project_id, content, **kwargs):
"""
Expand Down
2 changes: 1 addition & 1 deletion todoist/managers/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

class ProjectsManager(Manager, AllMixin, GetByIdMixin, SyncMixin):

state_name = 'Projects'
state_name = 'projects'
object_type = 'project'

def add(self, name, **kwargs):
Expand Down
2 changes: 1 addition & 1 deletion todoist/managers/reminders.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

class RemindersManager(Manager, AllMixin, GetByIdMixin, SyncMixin):

state_name = 'Reminders'
state_name = 'reminders'
object_type = 'reminder'

def add(self, item_id, **kwargs):
Expand Down

0 comments on commit bd2d025

Please sign in to comment.