-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfile.py
267 lines (233 loc) · 8.52 KB
/
file.py
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
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
import logging
import graphene
import django_rq
from django.db import transaction
from django.conf import settings
from graphene_file_upload.scalars import Upload
from graphql import GraphQLError
from graphql_relay import from_global_id
from creator.analyses.analyzer import analyze_version
from creator.files.models import File, Version
from creator.studies.models import Study
from creator.events.models import Event
from creator.files.nodes.file import FileNode, FileType
from creator.data_templates.models import TemplateVersion
from creator.storage_analyses.tasks.expected_file import (
prepare_audit_submission
)
logger = logging.getLogger(__name__)
class CreateFileMutation(graphene.Mutation):
class Arguments:
version = graphene.ID(
required=True,
description="The first version this document will contain",
)
study = graphene.ID(
required=False, description="The study this file will belong to"
)
name = graphene.String(
required=True, description="The name of the file"
)
description = graphene.String(
required=True, description="A description of this file"
)
fileType = FileType(required=True, description="The type of file")
tags = graphene.List(graphene.String)
templateVersion = graphene.ID(
required=False,
description="The template_version this file conforms to"
)
file = graphene.Field(FileNode)
def mutate(
self,
info,
version,
name,
description,
fileType,
tags,
study=None,
templateVersion=None,
**kwargs,
):
"""
Creates a new file housing the specified version.
"""
user = info.context.user
try:
_, version_id = from_global_id(version)
version = Version.objects.get(kf_id=version_id)
except Version.DoesNotExist:
raise GraphQLError("Version does not exist.")
# If there was a study in the mutation, try to resolve it, else try
# to inherit the study on the version, if there is one, otherwise fail
# to create a new file
if study is not None:
try:
_, study_id = from_global_id(study)
study = Study.objects.get(kf_id=study_id)
except Study.DoesNotExist:
raise GraphQLError("Study does not exist.")
else:
study = version.study
if study is None:
raise GraphQLError(
"Study must be specified or the version given must have a "
"linked study"
)
if not (
user.has_perm("files.add_file")
or (
user.has_perm("files.add_my_study_file")
and user.studies.filter(kf_id=study.kf_id).exists()
)
):
raise GraphQLError("Not allowed")
template_version = None
if templateVersion:
_, template_version_id = from_global_id(templateVersion)
try:
template_version = TemplateVersion.objects.get(
pk=template_version_id
)
except TemplateVersion.DoesNotExist:
raise GraphQLError(
f"TemplateVersion {template_version_id} does not exist"
)
with transaction.atomic():
root_file = File(
name=name,
study=study,
creator=user,
description=description,
file_type=fileType,
tags=tags,
template_version=template_version,
)
root_file.save()
version.root_file = root_file
version.save()
root_file.full_clean()
# If this is a File Upload Manifest, process it for audit submission
if (
settings.FEAT_DEWRANGLE_INTEGRATION and
version.is_file_upload_manifest
):
logger.info(
f"Queued version {version.kf_id} {version.file_name} for"
" audit processing..."
)
version.start_audit_prep()
version.save()
django_rq.enqueue(
prepare_audit_submission, args=(version.pk, )
)
return CreateFileMutation(file=root_file)
class FileMutation(graphene.Mutation):
class Arguments:
kf_id = graphene.String(required=True)
name = graphene.String()
description = graphene.String()
file_type = FileType()
tags = graphene.List(graphene.String)
template_version = graphene.ID()
file = graphene.Field(FileNode)
def mutate(self, info, kf_id, **kwargs):
"""
Updates an existing file on name and/or description.
User must be authenticated and belongs to the study, or be ADMIN.
"""
user = info.context.user
if not (
user.has_perm("files.change_file")
or user.has_perm("files.change_my_study_file")
):
raise GraphQLError("Not allowed")
try:
file = File.objects.get(kf_id=kf_id)
except File.DoesNotExist:
raise GraphQLError("File does not exist.")
if not (
user.has_perm("files.change_file")
or (
user.has_perm("files.change_my_study_file")
and user.studies.filter(kf_id=file.study.kf_id).exists()
)
):
raise GraphQLError("Not allowed")
update_fields = []
if kwargs.get("name"):
if file.name != kwargs.get("name"):
update_fields.append("name")
file.name = kwargs.get("name")
if kwargs.get("description"):
if file.description != kwargs.get("description"):
update_fields.append("description")
file.description = kwargs.get("description")
if kwargs.get("file_type"):
if file.file_type != kwargs.get("file_type"):
update_fields.append("file type")
file.file_type = kwargs.get("file_type")
if "tags" in kwargs:
if file.tags != kwargs.get("tags"):
update_fields.append("tags")
file.tags = kwargs.get("tags")
if (
kwargs.get("template_version") and
file.template_version != kwargs.get("template_version")
):
update_fields.append("file template")
# Update the file's template
template_version = kwargs.get("template_version")
if template_version:
_, template_version_id = from_global_id(template_version)
template_version = None
try:
template_version = TemplateVersion.objects.get(
pk=template_version_id
)
except TemplateVersion.DoesNotExist:
raise GraphQLError(
f"TemplateVersion {template_version_id} does not exist"
)
file.template_version = template_version
file.save()
# Make an update event
message = (
f"{user.display_name} updated {', '.join(update_fields)} "
f"{'of ' if len(update_fields)>0 else ''} file {file.kf_id}"
)
event = Event(
organization=file.study.organization,
file=file,
study=file.study,
user=user,
description=message,
event_type="SF_UPD",
)
event.save()
return FileMutation(file=file)
class DeleteFileMutation(graphene.Mutation):
class Arguments:
kf_id = graphene.String(required=True)
success = graphene.Boolean()
kf_id = graphene.String()
def mutate(self, info, kf_id, **kwargs):
"""
Deletes a file if the user is an admin and the file exists
"""
user = info.context.user
if not user.has_perm("files.delete_file"):
raise GraphQLError("Not allowed")
try:
file = File.objects.get(kf_id=kf_id)
except File.DoesNotExist:
raise GraphQLError("File does not exist.")
file.delete()
return DeleteFileMutation(success=True, kf_id=kf_id)
class Mutation(graphene.ObjectType):
create_file = CreateFileMutation.Field(
description="Upload a new file to a study"
)
update_file = FileMutation.Field(description="Update a file")
delete_file = DeleteFileMutation.Field(description="Delete a file")