class ServiceTodoist(ServicesMgr): def __init__(self, token=None, **kwargs): super(ServiceTodoist, self).__init__(token, **kwargs) self.AUTH_URL = 'https://todoist.com/oauth/authorize' self.ACC_TOKEN = 'https://todoist.com/oauth/access_token' self.REQ_TOKEN = 'https://todoist.com/oauth/access_token' self.consumer_key = settings.TH_TODOIST['client_id'] self.consumer_secret = settings.TH_TODOIST['client_secret'] self.scope = 'task:add,data:read,data:read_write' self.service = 'ServiceTodoist' self.oauth = 'oauth2' if token: self.token = token self.todoist = TodoistAPI(token) def read_data(self, **kwargs): """ get the data from the service as the pocket service does not have any date in its API linked to the note, add the triggered date to the dict data thus the service will be triggered when data will be found :param kwargs: contain keyword args : trigger_id at least :type kwargs: dict :rtype: list """ trigger_id = kwargs.get('trigger_id') date_triggered = kwargs.get('date_triggered') data = [] project_name = 'Main Project' items = self.todoist.sync() for item in items.get('items'): date_added = arrow.get(item.get('date_added'), 'ddd DD MMM YYYY HH:mm:ss ZZ') if date_added > date_triggered: for project in items.get('projects'): if item.get('project_id') == project.get('id'): project_name = project.get('name') data.append({'title': "From TodoIst Project {0}" ":".format(project_name), 'content': item.get('content')}) cache.set('th_todoist_' + str(trigger_id), data) return data def save_data(self, trigger_id, **data): """ let's save the data :param trigger_id: trigger ID from which to save data :param data: the data to check to be used and save :type trigger_id: int :type data: dict :return: the status of the save statement :rtype: boolean """ kwargs = {} title, content = super(ServiceTodoist, self).save_data(trigger_id, data, **kwargs) if self.token: if title or content or \ (data.get('link') and len(data.get('link'))) > 0: content = title + ' ' + content + ' ' + data.get('link') self.todoist.add_item(content) sentence = str('todoist {} created').format(data.get('link')) logger.debug(sentence) status = True else: status = False else: logger.critical("no token or link provided for " "trigger ID {} ".format(trigger_id)) status = False return status
class ServiceTodoist(ServicesMgr): """ service Todoist """ def __init__(self, token=None, **kwargs): super(ServiceTodoist, self).__init__(token, **kwargs) self.AUTH_URL = 'https://todoist.com/oauth/authorize' self.ACC_TOKEN = 'https://todoist.com/oauth/access_token' self.REQ_TOKEN = 'https://todoist.com/oauth/access_token' self.consumer_key = settings.TH_TODOIST_KEY['client_id'] self.consumer_secret = settings.TH_TODOIST_KEY['client_secret'] self.scope = 'task:add,data:read,data:read_write' self.service = 'ServiceTodoist' self.oauth = 'oauth2' if token: self.token = token self.todoist = TodoistAPI(token) def read_data(self, **kwargs): """ get the data from the service as the pocket service does not have any date in its API linked to the note, add the triggered date to the dict data thus the service will be triggered when data will be found :param kwargs: contain keyword args : trigger_id at least :type kwargs: dict :rtype: list """ trigger_id = kwargs.get('trigger_id') date_triggered = kwargs.get('date_triggered') data = [] project_name = 'Main Project' items = self.todoist.sync() try: for item in items.get('items'): date_added = arrow.get(item.get('date_added'), 'ddd DD MMM YYYY HH:mm:ss ZZ') if date_added > date_triggered: for project in items.get('projects'): if item.get('project_id') == project.get('id'): project_name = project.get('name') title = 'From TodoIst Project {0}:'.format(project_name) data.append({ 'title': title, 'content': item.get('content') }) # digester self.send_digest_event(trigger_id, title, '') cache.set('th_todoist_' + str(trigger_id), data) except AttributeError: logger.error(items) return data def save_data(self, trigger_id, **data): """ let's save the data :param trigger_id: trigger ID from which to save data :param data: the data to check to be used and save :type trigger_id: int :type data: dict :return: the status of the save statement :rtype: boolean """ title, content = super(ServiceTodoist, self).save_data(trigger_id, **data) if self.token: if title or content or \ (data.get('link') and len(data.get('link'))) > 0: content = title + ' ' + content + ' ' + data.get('link') self.todoist.add_item(content) sentence = str('todoist {} created').format(data.get('link')) logger.debug(sentence) status = True else: status = False else: logger.critical("no token or link provided for " "trigger ID {} ".format(trigger_id)) status = False return status
class TaskManager: def __init__(self): with open('.app.pass', 'r') as passFile: api_key = passFile.readline().strip() self.api = TodoistAPI(api_key) self.api.sync() # get the project into json format self.projects = self.__get_project_data() self.sections = self.__get_sections_data() self.collaborators = self.__get_collaborators() self.collaborator_states = self.__get_collaborator_states() def __get_project_data(self): tmp_projects = {} for project in self.api.projects.all(): tmp_projects[project['name']] = self.api.projects.get_data( project['id']) return tmp_projects def __get_sections_data(self): temp_sections = {} for section in self.api.sections.all(): temp_sections[section['name']] = section return temp_sections def __get_collaborators(self): tmp_collaborators = {} for collaborator in self.api.collaborators.state['collaborators']: collaborator_info = collaborator.__dict__.copy() collaborator_info = collaborator_info['data'] if collaborator_info.get('image_id') is not None: collaborator_info.pop('image_id') collaborator_info['task_load'] = 0 collaborator_info['tasks'] = [] tmp_collaborators[collaborator['id']] = collaborator_info return tmp_collaborators def __get_collaborator_states(self): tmp_collaborator_states = [] for collaborator_state in self.api.collaborator_states.state[ 'collaborator_states']: tmp_collaborator_states.append(collaborator_state) return tmp_collaborator_states def get_projects(self): return self.projects def get_sections(self): return self.sections def get_project_id(self, project_name): try: temp_project = self.projects.get(project_name) if temp_project is None: raise ProjectError('Project ' + project_name + 'does not exist') return temp_project['project']['id'] except ProjectError: print(ProjectError) def get_section_id(self, section_name): try: temp_section = self.sections.get(section_name) if temp_section is None: raise SectionError('Section ' + section_name + 'does not exist') return temp_section['id'] except SectionError: print(SectionError) def get_section(self, section): return self.sections.get(section) def get_sections(self): return self.sections def get_project(self, project_name): return self.projects.get(project_name) def get_section_from_project(self, project, section): temp_project = self.get_project(project) temp_section = [ x for x in temp_project['sections'] if x['name'] == section ] temp_section_data = self.api.sections.get(temp_section[0]['id']) return temp_section_data def get_tasks_from_project(self, project, sectionId=None, sectionName=None): temp_project = self.get_project(project) if sectionId or sectionName: if sectionName: sectionId = self.get_section_id(sectionName) temp_project_tasks = [ x for x in temp_project['items'] if x['section_id'] == sectionId ] return temp_project_tasks else: return temp_project['items'] def get_collaborators_from_project(self, project_name): project_id = self.get_project_id(project_name) collaborators = [] for collaborator_state in self.collaborator_states: if collaborator_state[ 'project_id'] == project_id and collaborator_state[ 'state'] == 'active': collaborators.append(collaborator_state['user_id']) if len(collaborators) > 0: for i, collaborator in zip(range(len(collaborators)), collaborators): collaborator_info = self.collaborators[collaborator] collaborators[i] = Assignee(collaborator_info['full_name'], collaborator_info['id'], collaborator_info['email'], collaborator_info['task_load'], collaborator_info['tasks'], collaborator_info['timezone']) else: # TODO: add error handling pass return collaborators def get_collaborator_from_user_id(self, user_id): return self.collaborators[user_id] def add_task(self, task_content, task_assignee: str = None, task_due_date: str = None, task_project: str = None, task_section: str = None): opts = { 'responsible_uid': '', 'due': '', 'project_id': '', 'section_id': '' } if task_project: opts['project_id'] = self.get_project_id(task_project) else: opts.pop('project_id') if task_assignee: opts['responsible_uid'] = task_assignee else: opts.pop('responsible_uid') if task_due_date: opts['due'] = task_due_date else: opts.pop('due') if task_section: opts['section_id'] = self.get_section_id(task_section) else: opts.pop('section_id') self.api.add_item(task_content, opts) def add_task_from_list(self, task_list): for task in task_list: task_content, opts = task.get_task_details() self.api.items.add(task_content, **opts) # TODO: add task updating functions def print_tasks(self, project=None, section=None): if section: if not project: raise AttributeError("Missing project name") print(self.get_tasks_from_project(project, section)) elif project: print(self.get_tasks_from_project(project)) else: projects = self.api.state['items'] print(projects) # def get_task_list(self, filename): # with open(filename, 'r') as taskListFile: # tasks = json.load(taskListFile) # task_list = [] # # for task in tasks['taskList']: # temp_task_content = task['content'] # temp_task_assignee = task['assignee'] # temp_task_due_date = task['due'] # temp_task_project = task['project'] # temp_task_section = task['section'] # task_list.append(Task(temp_task_content, temp_task_assignee, temp_task_due_date, temp_task_project, # temp_task_section)) # return task_list def write_tasks_to_file(self, filename, projectName=None, sectionID=None, sectionName=None): try: task_string = json.dumps({ 'taskList': self.get_tasks_from_project(projectName, sectionID, sectionName) }) with open(filename, 'w') as taskFile: taskFile.write(task_string) except IOError: print("Problem writing to file") def write_collaborators_to_file(self, filename, projectName=None): collaborator_dict = {'assignees': []} if projectName: collaborators = self.get_collaborators_from_project(projectName) tmp_collaborators = [x.__dict__ for x in collaborators] for collaborator in tmp_collaborators: collaborator["tasks"] = [ x.__dict__ for x in collaborator["tasks"] ] collaborator_dict['assignees'].extend(tmp_collaborators) else: for collaborator in self.collaborators: collaborator_dict['assignees'].append(collaborator) with open(filename, 'w') as collaborator_file: json.dump(collaborator_dict, collaborator_file) def commit_tasks(self): try: status = self.api.commit() return True except SyncError: return False def to_json(self): self.api.serialize() return json_default(self.api)