class RegistrationProviderSerializer(ProviderSerializer): class Meta: type_ = 'registration-providers' branded_discovery_page = ser.BooleanField(read_only=True) brand = RelationshipField( related_view='brands:brand-detail', related_view_kwargs={'brand_id': '<brand.id>'}, ) moderators = RelationshipField( related_view='providers:registration-providers:provider-moderator-list', related_view_kwargs={'provider_id': '<_id>'}, ) primary_collection = RelationshipField( related_view='collections:collection-detail', related_view_kwargs={'collection_id': '<primary_collection._id>'}, ) filterable_fields = frozenset([ 'allow_submissions', 'allow_commenting', 'brand', 'description', 'domain', 'domain_redirect_enabled', 'id', 'name', 'reviews_workflow', 'permissions', ]) reviews_workflow = ser.ChoiceField(choices=Workflows.choices(), read_only=True) reviews_comments_anonymous = ser.BooleanField(read_only=True) allow_updates = ser.BooleanField(read_only=True) allow_bulk_uploads = ser.BooleanField(read_only=True) registrations = ReviewableCountsRelationshipField( related_view='providers:registration-providers:registrations-list', related_view_kwargs={'provider_id': '<_id>'}, ) links = LinksField({ 'self': 'get_absolute_url', 'external_url': 'get_external_url', })
class PreprintProviderSerializer(ProviderSerializer): class Meta: type_ = 'preprint-providers' filterable_fields = frozenset([ 'allow_submissions', 'allow_commenting', 'description', 'domain', 'domain_redirect_enabled', 'id', 'name', 'share_publish_type', 'reviews_workflow', 'permissions', ]) share_source = ser.CharField(read_only=True) share_publish_type = ser.CharField(read_only=True) preprint_word = ser.CharField(read_only=True, allow_null=True) additional_providers = ser.ListField(read_only=True, child=ser.CharField()) permissions = ser.SerializerMethodField() # Reviews settings are the only writable fields reviews_workflow = ser.ChoiceField(choices=Workflows.choices()) reviews_comments_private = ser.BooleanField() reviews_comments_anonymous = ser.BooleanField() links = LinksField({ 'self': 'get_absolute_url', 'preprints': 'get_preprints_url', 'external_url': 'get_external_url' }) preprints = ReviewableCountsRelationshipField( related_view='providers:preprint-providers:preprints-list', related_view_kwargs={'provider_id': '<_id>'}) def get_preprints_url(self, obj): return absolute_reverse( 'providers:preprint-providers:preprints-list', kwargs={ 'provider_id': obj._id, 'version': self.context['request'].parser_context['kwargs']['version'] }) def get_permissions(self, obj): auth = get_user_auth(self.context['request']) if not auth.user: return [] return get_perms(auth.user, obj) def validate(self, data): required_fields = ('reviews_workflow', 'reviews_comments_private', 'reviews_comments_anonymous') for field in required_fields: if data.get(field) is None: raise ValidationError( 'All reviews fields must be set at once: `{}`'.format( '`, `'.join(required_fields))) return data def update(self, instance, validated_data): instance.reviews_workflow = validated_data['reviews_workflow'] instance.reviews_comments_private = validated_data[ 'reviews_comments_private'] instance.reviews_comments_anonymous = validated_data[ 'reviews_comments_anonymous'] instance.save() return instance
class ReviewProviderMixin(GuardianMixin): """A reviewed/moderated collection of objects. """ REVIEWABLE_RELATION_NAME = None groups = REVIEW_GROUPS group_format = 'reviews_{self.readable_type}_{self.id}_{group}' class Meta: abstract = True reviews_workflow = models.CharField(null=True, blank=True, max_length=15, choices=Workflows.choices()) reviews_comments_private = models.NullBooleanField() reviews_comments_anonymous = models.NullBooleanField() @property def is_reviewed(self): return self.reviews_workflow is not None def get_reviewable_state_counts(self): assert self.REVIEWABLE_RELATION_NAME, 'REVIEWABLE_RELATION_NAME must be set to compute state counts' qs = getattr(self, self.REVIEWABLE_RELATION_NAME) if isinstance(qs, IncludeQuerySet): qs = qs.include(None) qs = qs.filter(node__isnull=False, node__is_deleted=False, node__is_public=True).values('machine_state').annotate( count=models.Count('*')) counts = {state.value: 0 for state in ReviewStates} counts.update({ row['machine_state']: row['count'] for row in qs if row['machine_state'] in counts }) return counts def get_request_state_counts(self): # import stuff here to get around circular imports from osf.models import PreprintRequest qs = PreprintRequest.objects.filter(target__provider__id=self.id, target__node__isnull=False, target__node__is_deleted=False, target__node__is_public=True) qs = qs.values('machine_state').annotate(count=models.Count('*')) counts = {state.value: 0 for state in DefaultStates} counts.update({ row['machine_state']: row['count'] for row in qs if row['machine_state'] in counts }) return counts def add_to_group(self, user, group): # Add default notification subscription notification = self.notification_subscriptions.get( _id='{}_new_pending_submissions'.format(self._id)) user_id = user.id is_subscriber = notification.none.filter(id=user_id).exists() \ or notification.email_digest.filter(id=user_id).exists() \ or notification.email_transactional.filter(id=user_id).exists() if not is_subscriber: notification.add_user_to_subscription(user, 'email_transactional', save=True) return self.get_group(group).user_set.add(user) def remove_from_group(self, user, group, unsubscribe=True): _group = self.get_group(group) if group == 'admin': if _group.user_set.filter( id=user.id).exists() and not _group.user_set.exclude( id=user.id).exists(): raise ValueError('Cannot remove last admin.') if unsubscribe: # remove notification subscription notification = self.notification_subscriptions.get( _id='{}_new_pending_submissions'.format(self._id)) notification.remove_user_from_subscription(user, save=True) return _group.user_set.remove(user)