Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 23 additions & 18 deletions qiita_db/artifact.py
Original file line number Diff line number Diff line change
Expand Up @@ -458,11 +458,11 @@ def _associate_with_analysis(instance, analysis_id):
visibilities = {a.visibility for a in instance.parents}
# set based on the "lowest" visibility
if 'sandbox' in visibilities:
instance.visibility = 'sandbox'
instance._set_visibility('sandbox')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this change necessary? it looks like instance.visibility is a property where the setter calls _set_visibility

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some background: when an artifact is created, it will "copy" the parents visibility; however, right now the visibility "regular" setter (visibility) has a validation step that prevents this from happening. Thus, the "solution" is that for creation we use the new setter (_set_visibility) without validation and when we do whatever else we use the regular one, which has the validation ... AKA special case for artifact creation

elif 'private' in visibilities:
instance.visibility = 'private'
instance._set_visibility('private')
else:
instance.visibility = 'public'
instance._set_visibility('public')

elif prep_template:
# This artifact is uploaded by the user in the
Expand Down Expand Up @@ -737,6 +737,25 @@ def visibility(self):
qdb.sql_connection.TRN.add(sql, [self.id])
return qdb.sql_connection.TRN.execute_fetchlast()

def _set_visibility(self, value):
"helper method to split validation and actual set of the visibility"
# In order to correctly propagate the visibility we need to find
# the root of this artifact and then propagate to all the artifacts
vis_id = qdb.util.convert_to_id(value, "visibility")

sql = "SELECT * FROM qiita.find_artifact_roots(%s)"
qdb.sql_connection.TRN.add(sql, [self.id])
root_id = qdb.sql_connection.TRN.execute_fetchlast()
root = qdb.artifact.Artifact(root_id)
# these are the ids of all the children from the root
ids = [a.id for a in root.descendants.nodes()]

sql = """UPDATE qiita.artifact
SET visibility_id = %s
WHERE artifact_id IN %s"""
qdb.sql_connection.TRN.add(sql, [vis_id, tuple(ids)])
qdb.sql_connection.TRN.execute()

@visibility.setter
def visibility(self, value):
"""Sets the visibility of the artifact
Expand All @@ -753,7 +772,6 @@ def visibility(self, value):
"""
with qdb.sql_connection.TRN:
# first let's check that this is a valid visibility
vis_id = qdb.util.convert_to_id(value, "visibility")
study = self.study

# then let's check that the sample/prep info files have the correct
Expand All @@ -770,20 +788,7 @@ def visibility(self, value):
raise ValueError(
"Errors in your info files:%s" % '\n'.join(message))

# In order to correctly propagate the visibility we need to find
# the root of this artifact and then propagate to all the artifacts
sql = "SELECT * FROM qiita.find_artifact_roots(%s)"
qdb.sql_connection.TRN.add(sql, [self.id])
root_id = qdb.sql_connection.TRN.execute_fetchlast()
root = qdb.artifact.Artifact(root_id)
# these are the ids of all the children from the root
ids = [a.id for a in root.descendants.nodes()]

sql = """UPDATE qiita.artifact
SET visibility_id = %s
WHERE artifact_id IN %s"""
qdb.sql_connection.TRN.add(sql, [vis_id, tuple(ids)])
qdb.sql_connection.TRN.execute()
self._set_visibility(value)

@property
def artifact_type(self):
Expand Down