You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							360 lines
						
					
					
						
							9.9 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							360 lines
						
					
					
						
							9.9 KiB
						
					
					
				| from __future__ import annotations | |
| 
 | |
| from typing import List, Literal | |
| 
 | |
| import attr | |
| 
 | |
| from ..todoist_api_python.utils import get_url_for_task | |
| 
 | |
| VIEW_STYLE = Literal["list", "board"] | |
| 
 | |
| 
 | |
| @attr.s | |
| class Project(object): | |
|     color: str = attr.ib() | |
|     comment_count: int = attr.ib() | |
|     id: str = attr.ib() | |
|     is_favorite: bool = attr.ib() | |
|     is_inbox_project: bool = attr.ib() | |
|     is_shared: bool = attr.ib() | |
|     is_team_inbox: bool = attr.ib() | |
|     name: str = attr.ib() | |
|     order: int = attr.ib() | |
|     parent_id: str | None = attr.ib() | |
|     url: str = attr.ib() | |
|     view_style: VIEW_STYLE = attr.ib() | |
| 
 | |
|     @classmethod | |
|     def from_dict(cls, obj): | |
|         return cls( | |
|             color=obj["color"], | |
|             comment_count=obj["comment_count"], | |
|             id=obj["id"], | |
|             is_favorite=obj["is_favorite"], | |
|             is_inbox_project=obj.get("is_inbox_project"), | |
|             is_shared=obj["is_shared"], | |
|             is_team_inbox=obj.get("is_team_inbox"), | |
|             name=obj["name"], | |
|             order=obj.get("order"), | |
|             parent_id=obj.get("parent_id"), | |
|             url=obj["url"], | |
|             view_style=obj["view_style"], | |
|         ) | |
| 
 | |
| 
 | |
| @attr.s | |
| class Section(object): | |
|     id: str = attr.ib() | |
|     name: str = attr.ib() | |
|     order: int = attr.ib() | |
|     project_id: str = attr.ib() | |
| 
 | |
|     @classmethod | |
|     def from_dict(cls, obj): | |
|         return cls( | |
|             id=obj["id"], | |
|             name=obj["name"], | |
|             order=obj["order"], | |
|             project_id=obj["project_id"], | |
|         ) | |
| 
 | |
| 
 | |
| @attr.s | |
| class Due(object): | |
|     date: str = attr.ib() | |
|     is_recurring: bool = attr.ib() | |
|     string: str = attr.ib() | |
| 
 | |
|     datetime: str | None = attr.ib(default=None) | |
|     timezone: str | None = attr.ib(default=None) | |
| 
 | |
|     @classmethod | |
|     def from_dict(cls, obj): | |
|         return cls( | |
|             date=obj["date"], | |
|             is_recurring=obj["is_recurring"], | |
|             string=obj["string"], | |
|             datetime=obj.get("datetime"), | |
|             timezone=obj.get("timezone"), | |
|         ) | |
| 
 | |
|     def to_dict(self): | |
|         return { | |
|             "date": self.date, | |
|             "is_recurring": self.is_recurring, | |
|             "string": self.string, | |
|             "datetime": self.datetime, | |
|             "timezone": self.timezone, | |
|         } | |
| 
 | |
|     @classmethod | |
|     def from_quick_add_response(cls, obj): | |
|         due = obj.get("due") | |
| 
 | |
|         if not due: | |
|             return None | |
| 
 | |
|         timezone = due.get("timezone") | |
| 
 | |
|         datetime: str | None = None | |
| 
 | |
|         if timezone: | |
|             datetime = due["date"] | |
| 
 | |
|         return cls( | |
|             date=due["date"], | |
|             is_recurring=due["is_recurring"], | |
|             string=due["string"], | |
|             datetime=datetime, | |
|             timezone=timezone, | |
|         ) | |
| 
 | |
| 
 | |
| @attr.s | |
| class Task(object): | |
|     assignee_id: str | None = attr.ib() | |
|     assigner_id: str | None = attr.ib() | |
|     comment_count: int = attr.ib() | |
|     is_completed: bool = attr.ib() | |
|     content: str = attr.ib() | |
|     created_at: str = attr.ib() | |
|     creator_id: str = attr.ib() | |
|     description: str = attr.ib() | |
|     due: Due | None = attr.ib() | |
|     id: str = attr.ib() | |
|     labels: List[str] = attr.ib() | |
|     order: int = attr.ib() | |
|     parent_id: str | None = attr.ib() | |
|     priority: int = attr.ib() | |
|     project_id: str = attr.ib() | |
|     section_id: str | None = attr.ib() | |
|     url: str = attr.ib() | |
| 
 | |
|     sync_id: str | None = attr.ib(default=None) | |
| 
 | |
|     @classmethod | |
|     def from_dict(cls, obj): | |
|         due: Due | None = None | |
| 
 | |
|         if obj.get("due"): | |
|             due = Due.from_dict(obj["due"]) | |
| 
 | |
|         return cls( | |
|             assignee_id=obj.get("assignee_id"), | |
|             assigner_id=obj.get("assigner_id"), | |
|             comment_count=obj["comment_count"], | |
|             is_completed=obj["is_completed"], | |
|             content=obj["content"], | |
|             created_at=obj["created_at"], | |
|             creator_id=obj["creator_id"], | |
|             description=obj["description"], | |
|             due=due, | |
|             id=obj["id"], | |
|             labels=obj.get("labels"), | |
|             order=obj.get("order"), | |
|             parent_id=obj.get("parent_id"), | |
|             priority=obj["priority"], | |
|             project_id=obj["project_id"], | |
|             section_id=obj["section_id"], | |
|             url=obj["url"], | |
|         ) | |
| 
 | |
|     def to_dict(self): | |
|         due: dict | None = None | |
| 
 | |
|         if self.due: | |
|             due = self.due.to_dict() | |
| 
 | |
|         return { | |
|             "assignee_id": self.assignee_id, | |
|             "assigner_id": self.assigner_id, | |
|             "comment_count": self.comment_count, | |
|             "is_completed": self.is_completed, | |
|             "content": self.content, | |
|             "created_at": self.created_at, | |
|             "creator_id": self.creator_id, | |
|             "description": self.description, | |
|             "due": due, | |
|             "id": self.id, | |
|             "labels": self.labels, | |
|             "order": self.order, | |
|             "parent_id": self.parent_id, | |
|             "priority": self.priority, | |
|             "project_id": self.project_id, | |
|             "section_id": self.section_id, | |
|             "sync_id": self.sync_id, | |
|             "url": self.url, | |
|         } | |
| 
 | |
|     @classmethod | |
|     def from_quick_add_response(cls, obj): | |
|         due: Due | None = None | |
| 
 | |
|         if obj.get("due"): | |
|             due = Due.from_quick_add_response(obj) | |
| 
 | |
|         return cls( | |
|             assignee_id=obj.get("responsible_uid"), | |
|             assigner_id=obj.get("assigned_by_uid"), | |
|             comment_count=0, | |
|             is_completed=False, | |
|             content=obj["content"], | |
|             created_at=obj["added_at"], | |
|             creator_id=obj["added_by_uid"], | |
|             description=obj["description"], | |
|             due=due, | |
|             id=obj["id"], | |
|             labels=obj["labels"], | |
|             order=obj["child_order"], | |
|             parent_id=obj["parent_id"] or None, | |
|             priority=obj["priority"], | |
|             project_id=obj["project_id"], | |
|             section_id=obj["section_id"] or None, | |
|             sync_id=obj["sync_id"], | |
|             url=get_url_for_task(obj["id"], obj["sync_id"]), | |
|         ) | |
| 
 | |
| 
 | |
| @attr.s | |
| class QuickAddResult: | |
|     task: Task = attr.ib() | |
| 
 | |
|     resolved_project_name: str | None = attr.ib(default=None) | |
|     resolved_assignee_name: str | None = attr.ib(default=None) | |
|     resolved_label_names: List[str] | None = attr.ib(default=None) | |
|     resolved_section_name: str | None = attr.ib(default=None) | |
| 
 | |
|     @classmethod | |
|     def from_quick_add_response(cls, obj): | |
|         project_data = obj["meta"].get("project", {}) | |
|         assignee_data = obj["meta"].get("assignee", {}) | |
|         section_data = obj["meta"].get("section", {}) | |
| 
 | |
|         resolved_project_name = None | |
|         resolved_assignee_name = None | |
|         resolved_section_name = None | |
| 
 | |
|         if project_data and len(project_data) == 2: | |
|             resolved_project_name = obj["meta"]["project"][1] | |
| 
 | |
|         if assignee_data and len(assignee_data) == 2: | |
|             resolved_assignee_name = obj["meta"]["assignee"][1] | |
| 
 | |
|         if section_data and len(section_data) == 2: | |
|             resolved_section_name = obj["meta"]["section"][1] | |
| 
 | |
|         return cls( | |
|             task=Task.from_quick_add_response(obj), | |
|             resolved_project_name=resolved_project_name, | |
|             resolved_assignee_name=resolved_assignee_name, | |
|             resolved_label_names=list(obj["meta"]["labels"].values()), | |
|             resolved_section_name=resolved_section_name, | |
|         ) | |
| 
 | |
| 
 | |
| @attr.s | |
| class Collaborator(object): | |
|     id: str = attr.ib() | |
|     email: str = attr.ib() | |
|     name: str = attr.ib() | |
| 
 | |
|     @classmethod | |
|     def from_dict(cls, obj): | |
|         return cls( | |
|             id=obj["id"], | |
|             email=obj["email"], | |
|             name=obj["name"], | |
|         ) | |
| 
 | |
| 
 | |
| @attr.s | |
| class Attachment(object): | |
|     resource_type: str | None = attr.ib(default=None) | |
| 
 | |
|     file_name: str | None = attr.ib(default=None) | |
|     file_size: int | None = attr.ib(default=None) | |
|     file_type: str | None = attr.ib(default=None) | |
|     file_url: str | None = attr.ib(default=None) | |
|     file_duration: int | None = attr.ib(default=None) | |
|     upload_state: str | None = attr.ib(default=None) | |
| 
 | |
|     image: str | None = attr.ib(default=None) | |
|     image_width: int | None = attr.ib(default=None) | |
|     image_height: int | None = attr.ib(default=None) | |
| 
 | |
|     url: str | None = attr.ib(default=None) | |
|     title: str | None = attr.ib(default=None) | |
| 
 | |
|     @classmethod | |
|     def from_dict(cls, obj): | |
|         return cls( | |
|             resource_type=obj.get("resource_type"), | |
|             file_name=obj.get("file_name"), | |
|             file_size=obj.get("file_size"), | |
|             file_type=obj.get("file_type"), | |
|             file_url=obj.get("file_url"), | |
|             upload_state=obj.get("upload_state"), | |
|             image=obj.get("image"), | |
|             image_width=obj.get("image_width"), | |
|             image_height=obj.get("image_height"), | |
|             url=obj.get("url"), | |
|             title=obj.get("title"), | |
|         ) | |
| 
 | |
| 
 | |
| @attr.s | |
| class Comment(object): | |
|     attachment: Attachment | None = attr.ib() | |
|     content: str = attr.ib() | |
|     id: str = attr.ib() | |
|     posted_at: str = attr.ib() | |
|     project_id: str | None = attr.ib() | |
|     task_id: str | None = attr.ib() | |
| 
 | |
|     @classmethod | |
|     def from_dict(cls, obj): | |
|         attachment: Attachment | None = None | |
| 
 | |
|         if "attachment" in obj and obj["attachment"] is not None: | |
|             attachment = Attachment.from_dict(obj["attachment"]) | |
| 
 | |
|         return cls( | |
|             attachment=attachment, | |
|             content=obj["content"], | |
|             id=obj["id"], | |
|             posted_at=obj["posted_at"], | |
|             project_id=obj.get("project_id"), | |
|             task_id=obj.get("task_id"), | |
|         ) | |
| 
 | |
| 
 | |
| @attr.s | |
| class Label: | |
|     id: str = attr.ib() | |
|     name: str = attr.ib() | |
|     color: str = attr.ib() | |
|     order: int = attr.ib() | |
|     is_favorite: bool = attr.ib() | |
| 
 | |
|     @classmethod | |
|     def from_dict(cls, obj): | |
|         return cls( | |
|             id=obj["id"], | |
|             name=obj["name"], | |
|             color=obj["color"], | |
|             order=obj["order"], | |
|             is_favorite=obj["is_favorite"], | |
|         ) | |
| 
 | |
| 
 | |
| @attr.s | |
| class AuthResult: | |
|     access_token: str = attr.ib() | |
|     state: str = attr.ib() | |
| 
 | |
|     @classmethod | |
|     def from_dict(cls, obj): | |
|         return cls( | |
|             access_token=obj["access_token"], | |
|             state=obj["state"], | |
|         )
 | |
| 
 |