File: models.py

package info (click to toggle)
todoist-api-python 3.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 520 kB
  • sloc: python: 3,822; makefile: 3
file content (220 lines) | stat: -rw-r--r-- 5,650 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
from __future__ import annotations

from dataclasses import dataclass
from typing import Annotated, Literal, Optional, Union

from dataclass_wizard import JSONPyWizard
from dataclass_wizard.v1 import DatePattern, DateTimePattern, UTCDateTimePattern
from dataclass_wizard.v1.models import Alias

from todoist_api_python._core.endpoints import INBOX_URL, get_project_url, get_task_url

ViewStyle = Literal["list", "board", "calendar"]
DurationUnit = Literal["minute", "day"]
ApiDate = UTCDateTimePattern["%FT%T.%fZ"]  # type: ignore[valid-type]
ApiDue = Union[  # https://github.com/rnag/dataclass-wizard/issues/189
    DatePattern["%F"], DateTimePattern["%FT%T"], UTCDateTimePattern["%FT%TZ"]  # type: ignore[valid-type]  # noqa: F722
]


@dataclass
class Project(JSONPyWizard):
    class _(JSONPyWizard.Meta):  # noqa:N801
        v1 = True

    id: str
    name: str
    description: str
    order: Annotated[int, Alias(load=("child_order", "order"))]
    color: str
    is_collapsed: Annotated[bool, Alias(load=("collapsed", "is_collapsed"))]
    is_shared: Annotated[bool, Alias(load=("shared", "is_shared"))]
    is_favorite: bool
    is_archived: bool
    can_assign_tasks: bool
    view_style: ViewStyle
    created_at: ApiDate
    updated_at: ApiDate

    parent_id: str | None = None
    is_inbox_project: Annotated[
        bool | None, Alias(load=("inbox_project", "is_inbox_project"))
    ] = None

    workspace_id: str | None = None
    folder_id: str | None = None

    @property
    def url(self) -> str:
        if self.is_inbox_project:
            return INBOX_URL
        return get_project_url(self.id, self.name)


@dataclass
class Section(JSONPyWizard):
    class _(JSONPyWizard.Meta):  # noqa:N801
        v1 = True

    id: str
    name: str
    project_id: str
    is_collapsed: Annotated[bool, Alias(load=("collapsed", "is_collapsed"))]
    order: Annotated[int, Alias(load=("section_order", "order"))]


@dataclass
class Due(JSONPyWizard):
    class _(JSONPyWizard.Meta):  # noqa:N801
        v1 = True

    date: ApiDue
    string: str
    lang: str = "en"
    is_recurring: bool = False
    timezone: str | None = None


@dataclass
class Deadline(JSONPyWizard):
    class _(JSONPyWizard.Meta):  # noqa:N801
        v1 = True

    date: ApiDue
    lang: str = "en"


@dataclass
class Meta(JSONPyWizard):
    class _(JSONPyWizard.Meta):  # noqa:N801
        v1 = True

    project: tuple[str, str]
    section: tuple[str, str]
    assignee: tuple[str, str]
    labels: dict[int, str]
    due: Due | None
    deadline: Deadline | None


@dataclass
class Task(JSONPyWizard):
    class _(JSONPyWizard.Meta):  # noqa:N801
        v1 = True

    id: str
    content: str
    description: str
    project_id: str
    section_id: str | None
    parent_id: str | None
    labels: list[str] | None
    priority: int
    due: Due | None
    deadline: Deadline | None
    duration: Duration | None
    is_collapsed: Annotated[bool, Alias(load=("collapsed", "is_collapsed"))]
    order: Annotated[int, Alias(load=("child_order", "order"))]
    assignee_id: Annotated[str | None, Alias(load=("responsible_uid", "assignee_id"))]
    assigner_id: Annotated[str | None, Alias(load=("assigned_by_uid", "assigner_id"))]
    completed_at: Optional[ApiDate]  # noqa: UP007 # https://github.com/rnag/dataclass-wizard/issues/189
    creator_id: Annotated[str, Alias(load=("added_by_uid", "creator_id"))]
    created_at: Annotated[ApiDate, Alias(load=("added_at", "created_at"))]
    updated_at: ApiDate

    meta: Meta | None = None

    @property
    def url(self) -> str:
        return get_task_url(self.id, self.content)

    @property
    def is_completed(self) -> bool:
        return self.completed_at is not None


@dataclass
class Collaborator(JSONPyWizard):
    class _(JSONPyWizard.Meta):  # noqa:N801
        v1 = True

    id: str
    email: str
    name: str


@dataclass
class Attachment(JSONPyWizard):
    class _(JSONPyWizard.Meta):  # noqa:N801
        v1 = True

    resource_type: str | None = None

    file_name: str | None = None
    file_size: int | None = None
    file_type: str | None = None
    file_url: str | None = None
    file_duration: int | None = None
    upload_state: str | None = None

    image: str | None = None
    image_width: int | None = None
    image_height: int | None = None

    url: str | None = None
    title: str | None = None


@dataclass
class Comment(JSONPyWizard):
    class _(JSONPyWizard.Meta):  # noqa:N801
        v1 = True

    id: str
    content: str
    poster_id: Annotated[str, Alias(load=("posted_uid", "poster_id"))]
    posted_at: ApiDate
    task_id: Annotated[str | None, Alias(load=("item_id", "task_id"))] = None
    project_id: str | None = None
    attachment: Annotated[
        Attachment | None, Alias(load=("file_attachment", "attachment"))
    ] = None

    def __post_init__(self) -> None:
        """
        Finish initialization of the Comment object.

        :raises ValueError: If neither `task_id` nor `project_id` is specified.
        """
        if self.task_id is None and self.project_id is None:
            raise ValueError("Must specify `task_id` or `project_id`")


@dataclass
class Label(JSONPyWizard):
    class _(JSONPyWizard.Meta):  # noqa:N801
        v1 = True

    id: str
    name: str
    color: str
    order: int
    is_favorite: bool


@dataclass
class AuthResult(JSONPyWizard):
    class _(JSONPyWizard.Meta):  # noqa:N801
        v1 = True

    access_token: str
    state: str | None


@dataclass
class Duration(JSONPyWizard):
    class _(JSONPyWizard.Meta):  # noqa:N801
        v1 = True

    amount: int
    unit: DurationUnit