Skip to content

Commit

Permalink
add stuff to allow institutional affiliations for Preprints
Browse files Browse the repository at this point in the history
  • Loading branch information
John Tordoff committed Jun 21, 2024
1 parent aa426e4 commit 99550c1
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 5 deletions.
15 changes: 15 additions & 0 deletions api/preprints/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,15 @@ class PreprintSerializer(TaxonomizableSerializerMixin, MetricsSerializerMixin, J
related_view_kwargs={'preprint_id': '<_id>'},
))

affiliated_institutions = RelationshipField(
related_view='preprints:preprints-affiliated-institutions',
related_view_kwargs={'preprint_id': '<_id>'},
self_view='preprints:preprints-affiliated-institutions',
self_view_kwargs={'preprint_id': '<_id>'},
read_only=False,
required=False,
)

links = LinksField(
{
'self': 'get_preprint_url',
Expand Down Expand Up @@ -380,6 +389,12 @@ def update(self, preprint, validated_data):
except PreprintStateError as e:
raise exceptions.ValidationError(detail=str(e))

if 'affiliated_institutions' in validated_data:
try:
preprint.update_institutional_affiliation(auth, validated_data['affiliated_institutions'])
except PreprintStateError as e:
raise exceptions.ValidationError(detail=str(e))

if published is not None:
if not preprint.primary_file:
raise exceptions.ValidationError(detail='A valid primary_file must be set before publishing a preprint.')
Expand Down
18 changes: 18 additions & 0 deletions osf/migrations/0021_preprint_affiliated_institutions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.2.17 on 2024-06-21 16:25

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('osf', '0020_abstractprovider_advertise_on_discover_page'),
]

operations = [
migrations.AddField(
model_name='preprint',
name='affiliated_institutions',
field=models.ManyToManyField(related_name='preprints', to='osf.Institution'),
),
]
39 changes: 36 additions & 3 deletions osf/models/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,8 @@ class AffiliatedInstitutionMixin(models.Model):

def add_affiliated_institution(self, inst, user, save=False, log=True):
if not user.is_affiliated_with_institution(inst):
raise UserNotAffiliatedError('User is not affiliated with {}'.format(inst.name))
raise UserNotAffiliatedError(f'User is not affiliated with {inst.name}')

if not self.is_affiliated_with_institution(inst):
self.affiliated_institutions.add(inst)
self.update_search()
Expand All @@ -315,6 +316,11 @@ def add_affiliated_institution(self, inst, user, save=False, log=True):
auth=Auth(user)
)

if save:
self.save()

self.update_search()

def remove_affiliated_institution(self, inst, user, save=False, log=True):
if self.is_affiliated_with_institution(inst):
self.affiliated_institutions.remove(inst)
Expand All @@ -332,8 +338,35 @@ def remove_affiliated_institution(self, inst, user, save=False, log=True):
if save:
self.save()
self.update_search()
return True
return False

def update_institutional_affiliation(self, institution_ids, user):

current_institutions = set(self.affiliated_institutions.values_list('id', flat=True))

institutions_to_add = set(institution_ids) - current_institutions
institutions_to_remove = current_institutions - set(institution_ids)

Institution = apps.get_model('osf.Institution')

for institution_id in institutions_to_add:
try:
institution = Institution.objects.get(id=institution_id)
self.add_affiliated_institution(institution, user, save=False, log=True)
except Institution.DoesNotExist:
raise UserNotAffiliatedError(f'User is not affiliated with {institution.name},'
f' it was not found in records')

for institution_id in institutions_to_remove:
try:
institution = Institution.objects.get(id=institution_id)
self.remove_affiliated_institution(institution, user, save=False, log=True)
except Institution.DoesNotExist:
raise UserNotAffiliatedError(f'User is not affiliated with {institution.name},'
f' it was not found in records')

self.save()

self.update_search()

def is_affiliated_with_institution(self, institution):
return self.affiliated_institutions.filter(id=institution.id).exists()
Expand Down
7 changes: 5 additions & 2 deletions osf/models/preprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from .provider import PreprintProvider
from .preprintlog import PreprintLog
from .contributor import PreprintContributor
from .mixins import ReviewableMixin, Taggable, Loggable, GuardianMixin
from .mixins import ReviewableMixin, Taggable, Loggable, GuardianMixin, AffiliatedInstitutionMixin
from .validators import validate_doi
from osf.utils.fields import NonNaiveDateTimeField
from osf.utils.workflows import DefaultStates, ReviewStates
Expand Down Expand Up @@ -109,7 +109,7 @@ def can_view(self, base_queryset=None, user=None, allow_contribs=True, public_on


class Preprint(DirtyFieldsMixin, GuidMixin, IdentifierMixin, ReviewableMixin, BaseModel, TitleMixin, DescriptionMixin,
Loggable, Taggable, ContributorMixin, GuardianMixin, SpamOverrideMixin, TaxonomizableMixin):
Loggable, Taggable, ContributorMixin, GuardianMixin, SpamOverrideMixin, TaxonomizableMixin, AffiliatedInstitutionMixin):

objects = PreprintManager()
# Preprint fields that trigger a check to the spam filter on save
Expand Down Expand Up @@ -142,6 +142,9 @@ class Preprint(DirtyFieldsMixin, GuidMixin, IdentifierMixin, ReviewableMixin, Ba
('not_applicable', 'Not applicable')
]

# overrides AffiliatedInstitutionMixin
affiliated_institutions = models.ManyToManyField('Institution', related_name='preprints')

provider = models.ForeignKey('osf.PreprintProvider',
on_delete=models.SET_NULL,
related_name='preprints',
Expand Down

0 comments on commit 99550c1

Please sign in to comment.