-
Notifications
You must be signed in to change notification settings - Fork 25
Expand file tree
/
Copy pathtypes.py
More file actions
244 lines (193 loc) · 7.12 KB
/
types.py
File metadata and controls
244 lines (193 loc) · 7.12 KB
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
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
from typing import Annotated
from submissions.models import Submission as SubmissionModel
from files_upload.models import File
from api.utils import validate_url
from participants.models import Participant as ParticipantModel
import strawberry
from strawberry.types.field import StrawberryField
from strawberry.types import Info
from api.languages.types import Language
from api.voting.types import VoteType
from i18n.strings import LazyI18nString
from voting.models import Vote
from .permissions import CanSeeSubmissionPrivateFields, CanSeeSubmissionRestrictedFields
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from api.conferences.types import Conference, Topic, Duration, AudienceLevel
from api.schedule.types import ScheduleItem
from api.participants.types import Participant
from api.submissions.mutations import SendSubmissionErrors
def private_field() -> StrawberryField:
"""Field that can only be seen by admin and the submitter"""
def resolver(self, info: Info):
if CanSeeSubmissionPrivateFields().has_permission(self, info):
return getattr(self, info.python_name)
return None
return strawberry.field(resolver=resolver)
@strawberry.type
class SubmissionType:
id: strawberry.ID
name: str
is_recordable: bool
@strawberry.type
class SubmissionTag:
id: strawberry.ID
name: str
@strawberry.type
class SubmissionSpeaker:
id: strawberry.ID
full_name: str
gender: str
_conference_id: strawberry.Private[str]
@strawberry.field
def participant(
self, info: Info
) -> Annotated["Participant", strawberry.lazy("api.participants.types")] | None:
from api.participants.types import Participant
participant = (
ParticipantModel.objects.for_conference(self._conference_id)
.filter(user_id=self.id)
.first()
)
return Participant.from_model(participant) if participant else None
@strawberry.type
class MultiLingualString:
it: str
en: str
@classmethod
def create(cls, string: LazyI18nString):
return cls(
en=string.data.get("en", ""),
it=string.data.get("it", ""),
)
@strawberry.type
class ProposalMaterial:
id: strawberry.ID
name: str
url: str | None
file_id: str | None
file_url: str | None
file_mime_type: str | None
@classmethod
def from_django(cls, material):
return cls(
id=material.id,
name=material.name,
url=material.url,
file_id=material.file_id,
file_url=material.file.url if material.file_id else None,
file_mime_type=material.file.mime_type if material.file_id else None,
)
@strawberry.type
class Submission:
conference: Annotated["Conference", strawberry.lazy("api.conferences.types")]
title: str
slug: str
status: str
speaker_level: str | None = private_field()
previous_talk_video: str | None = private_field()
short_social_summary: str | None = private_field()
topic: Annotated["Topic", strawberry.lazy("api.conferences.types")] | None
type: SubmissionType | None
duration: Annotated["Duration", strawberry.lazy("api.conferences.types")] | None
audience_level: (
Annotated["AudienceLevel", strawberry.lazy("api.conferences.types")] | None
)
notes: str | None = private_field()
do_not_record: bool | None = private_field()
@strawberry.field
def schedule_items(
self, info: Info
) -> list[Annotated["ScheduleItem", strawberry.lazy("api.schedule.types")]]:
return self.schedule_items.all()
@strawberry.field
def multilingual_elevator_pitch(self, info: Info) -> MultiLingualString | None:
return MultiLingualString.create(self.elevator_pitch)
@strawberry.field
def multilingual_abstract(self, info: Info) -> MultiLingualString | None:
return MultiLingualString.create(self.abstract)
@strawberry.field
def multilingual_title(self, info: Info) -> MultiLingualString | None:
return MultiLingualString.create(self.title)
@strawberry.field
def title(self, language: str) -> str:
return self.title.localize(language)
@strawberry.field()
def elevator_pitch(self, language: str, info: Info) -> str | None:
return self.elevator_pitch.localize(language)
@strawberry.field()
def abstract(self, language: str, info: Info) -> str | None:
return self.abstract.localize(language)
@strawberry.field
def speaker(self, info: Info) -> SubmissionSpeaker | None:
if not CanSeeSubmissionRestrictedFields().has_permission(
self, info, is_speaker_data=True
):
return None
return SubmissionSpeaker(
id=self.speaker_id,
full_name=self.speaker.full_name,
gender=self.speaker.gender,
_conference_id=self.conference_id,
)
@strawberry.field
def id(self, info: Info) -> strawberry.ID:
return self.hashid
@strawberry.field
def can_edit(self, info: Info) -> bool:
return self.can_edit(info.context.request)
@strawberry.field
def my_vote(self, info: Info) -> VoteType | None:
request = info.context.request
if not request.user.is_authenticated:
return None
if info.context._my_votes is not None:
return info.context._my_votes.get(self.id)
try:
return self.votes.get(user_id=request.user.id)
except Vote.DoesNotExist:
return None
@strawberry.field
def languages(self, info: Info) -> list[Language] | None:
return self.languages.all()
@strawberry.field
def tags(self, info: Info) -> list[SubmissionTag] | None:
return self.tags.all()
@strawberry.field
def materials(self, info: Info) -> list[ProposalMaterial]:
return [
ProposalMaterial.from_django(material)
for material in self.materials.order_by("created").all()
]
@strawberry.type
class SubmissionsPagination:
submissions: list[Submission]
total_pages: int
@strawberry.input
class SubmissionMaterialInput:
name: str
id: strawberry.ID | None = None
url: str | None = None
file_id: str | None = None
def validate(
self, errors: "SendSubmissionErrors", submission: SubmissionModel
) -> "SendSubmissionErrors":
if self.id:
try:
if not submission.materials.filter(id=int(self.id)).exists():
errors.add_error("id", "Material not found")
except ValueError:
errors.add_error("id", "Invalid material id")
if self.file_id:
if not File.objects.filter(
id=self.file_id,
uploaded_by_id=submission.speaker_id,
type=File.Type.PROPOSAL_MATERIAL,
).exists():
errors.add_error("file_id", "File not found")
if self.url:
if len(self.url) > 2048:
errors.add_error("url", "URL is too long")
elif not validate_url(self.url):
errors.add_error("url", "Invalid URL")
return errors