Skip to content

Commit

Permalink
fix(WIP): remove affiliations and unneeded logic
Browse files Browse the repository at this point in the history
TODO: go through how `is_mutable` and related guards should work with
@asuworks and @sgfost
  • Loading branch information
alee committed May 29, 2024
1 parent ec40a2f commit 364a346
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 87 deletions.
101 changes: 29 additions & 72 deletions django/library/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,22 +66,19 @@ class ContributorSerializer(serializers.ModelSerializer):
# Need an ID for Vue-Multiselect
id = serializers.IntegerField(read_only=True)
user = RelatedUserSerializer(required=False, allow_null=True)
affiliations = TagSerializer(many=True)

json_affiliations = models.JSONField(
default=list, help_text=_("JSON-LD list of affiliated institutions")
)
mutable = serializers.SerializerMethodField(read_only=True)
mutable = serializers.SerializerMethodField(method_name="is_mutable")

profile_url = serializers.SerializerMethodField(read_only=True)
profile_url = serializers.SerializerMethodField()

def get_mutable(self, obj):
def is_mutable(self, obj):
return self._is_exclusive_to_one_codebase(obj)

def _trying_to_modify_attributes(self, instance, validated_data):
try:
for key in [
"id",
"user_id",
"given_name",
"middle_name",
Expand All @@ -95,55 +92,26 @@ def _trying_to_modify_attributes(self, instance, validated_data):
and getattr(instance, key) != validated_data[key]
):
logger.debug(
f"{key} is not the same! {getattr(instance, key)} != {validated_data[key]}. Contributors can only be updated when they are exclusive to one codebase"
"[key %s] has different incoming value %s != %s - Contributors can only be updated when exclusive to one codebase",
key,
instance_dict[key],
validated_data[key],
)
return True
logger.debug(f"not trying to update, all attributes match!")
logger.debug("no update detected, all attributes match")
return False
except Exception as e:
logger.error(f"Some Exception here {e}")
logger.exception(e)
return True

def _is_exclusive_to_one_codebase(self, obj):
distinct_codebases = (
ReleaseContributor.objects.filter(contributor=obj)
.values_list("release__codebase", flat=True)
.distinct()
return (
Codebase.objects.filter(
releases__codebase_contributors__contributor=obj
).count()
<= 1
)

times_used_in_codebases = distinct_codebases.count()
return times_used_in_codebases <= 1

def _is_not_used_or_used_by_current_release_only(self, contributor):
# codebase instead of release so we allow a submitter to update a contributor on their own codebase
release_id = self.context.get("release_id")
if not release_id:
return False

distinct_codebases = (
ReleaseContributor.objects.filter(contributor=contributor)
.values_list("release__codebase", flat=True)
.distinct()
)

times_used_in_codebases = distinct_codebases.count()
logger.debug(f"distinct_codebases={distinct_codebases}")

if times_used_in_codebases == 0:
return True
elif times_used_in_codebases == 1:
if (
ReleaseContributor.objects.filter(contributor=contributor)
.first()
.release_id
== release_id
):
return True
else:
return False
else:
return False

def get_existing_contributor(self, validated_data):
user = validated_data.get("user")
username = user.get("username") if user else None
Expand All @@ -152,10 +120,13 @@ def get_existing_contributor(self, validated_data):
# attempt to find contributor by username, then email, then name without an email
if username:
user = User.objects.filter(username=username).first()
contributor = Contributor.objects.filter(user__username=username).first()
if user:
contributor = Contributor.objects.filter(user=user).first()
elif email:
user = User.objects.filter(email=email).first()
contributor = Contributor.objects.filter(email=email).first()
user = contributor.user if contributor else None
if not user:
user = contributor.user if contributor else None
else:
contrib_filter = {
k: validated_data.get(k, "")
Expand Down Expand Up @@ -188,22 +159,22 @@ def get_profile_url(self, instance):
)

def update(self, instance, validated_data):
if not self._is_not_used_or_used_by_current_release_only(instance):
if self._trying_to_modify_attributes(instance, validated_data):
raise ValidationError(
_(
"Contributors can only be updated when they are exclusive to one codebase"
)
if not self.is_mutable(instance) and self._trying_to_modify_attributes(
instance, validated_data
):
raise ValidationError(
_(
"Contributors can only be updated when they are exclusive to one codebase"
)
)
# Server side validation:
# if a contributor is made from a user, do not allow to modify it's data.
# if a contributor proxies a User, do not allow modification of its data.
# POP following:
# 'given_name'
# 'middle_name'
# 'family_name'
# 'email'
# 'type'
# 'affiliations'
# 'json_affiliations'
user_id = validated_data.pop("user_id", None)
if user_id:
Expand All @@ -212,27 +183,15 @@ def update(self, instance, validated_data):
validated_data.pop("family_name", None)
validated_data.pop("email", None)
validated_data.pop("type", None)
validated_data.pop("affiliations", None)
validated_data.pop("json_affiliations", None)

instance = super().update(instance, validated_data)
# affiliations = validated_data.pop("affiliations", None)
#
# if affiliations: # dont overwrite affiliations if not provided
# affiliations_serializer = TagSerializer(
# many=True, data=affiliations, context=self.context
# )
# set_tags(instance, affiliations_serializer, "affiliations")
instance.save()
return instance

def create(self, validated_data):
print(f"CREATE TRIGGERED with: {validated_data}")
affiliations_serializer = TagSerializer(
many=True, data=validated_data.pop("affiliations")
)
logger.debug("CREATE with: %s", validated_data)
instance = super().create(validated_data)
set_tags(instance, affiliations_serializer, "affiliations")
instance.save()
return instance

Expand All @@ -247,9 +206,7 @@ class Meta:
"email",
"user",
"type",
"affiliations",
"json_affiliations",
"primary_affiliation_name",
"primary_json_affiliation_name",
"profile_url",
"mutable",
Expand Down Expand Up @@ -329,7 +286,7 @@ def get_featured_image(self, instance):

class ReleaseContributorSerializer(serializers.ModelSerializer):
contributor = ContributorSerializer()
profile_url = serializers.SerializerMethodField(read_only=True)
profile_url = serializers.SerializerMethodField()
index = serializers.IntegerField(required=False)

def get_profile_url(self, instance):
Expand Down
30 changes: 15 additions & 15 deletions frontend/src/components/releaseEditor/ContributorEditForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -269,27 +269,27 @@ const hasName = computed(() => values.user || values.givenName);
// used to disable UI inputs if prefilled from existing user or contributor is not mutable (some other release uses the contributor)
const fromUser = computed(() => !!values.user || !values.mutable);
function populateFromReleaseContributor(contributor: ReleaseContributor) {
const user = contributor.contributor.user;
function populateFromReleaseContributor(releaseContributor: ReleaseContributor) {
const user = releaseContributor.contributor.user;
// Contributor has an associated user! Take values from the user.
const givenName = user ? user.memberProfile.givenName : contributor.contributor.givenName;
const familyName = user ? user.memberProfile.familyName : contributor.contributor.familyName;
// releaseContributor has an associated user! Take values from the user.
const givenName = user ? user.memberProfile.givenName : releaseContributor.contributor.givenName;
const familyName = user ? user.memberProfile.familyName : releaseContributor.contributor.familyName;
setValues({
// set this to get the id from autocomplete contributor
// id: contributor.contributor.id,
user: contributor.contributor.user || null,
email: contributor.contributor.email,
// id: releaseContributor.contributor.id,
user: releaseContributor.contributor.user || null,
email: releaseContributor.contributor.email,
givenName: givenName,
familyName: familyName,
middleName: contributor.contributor.middleName,
affiliations: contributor.contributor.affiliations,
jsonAffiliations: contributor.contributor.jsonAffiliations,
mutable: contributor.contributor.mutable,
type: contributor.contributor.type,
roles: contributor.roles,
includeInCitation: contributor.includeInCitation,
middleName: releaseContributor.contributor.middleName,
affiliations: releaseContributor.contributor.affiliations,
jsonAffiliations: releaseContributor.contributor.jsonAffiliations,
mutable: releaseContributor.contributor.mutable,
type: releaseContributor.contributor.type,
roles: releaseContributor.roles,
includeInCitation: releaseContributor.includeInCitation,
});
}
Expand Down

0 comments on commit 364a346

Please sign in to comment.