示例#1
0
class OembedSerializer(serializers.Serializer):
    format = serializers.ChoiceField(choices=["json"])
    url = serializers.URLField()
    maxheight = serializers.IntegerField(required=False)
    maxwidth = serializers.IntegerField(required=False)

    def validate(self, validated_data):
        try:
            match = common_utils.spa_resolve(
                urllib.parse.urlparse(validated_data["url"]).path
            )
        except urls.exceptions.Resolver404:
            raise serializers.ValidationError(
                "Invalid URL {}".format(validated_data["url"])
            )
        data = {
            "version": "1.0",
            "type": "rich",
            "provider_name": settings.APP_NAME,
            "provider_url": settings.FUNKWHALE_URL,
            "height": validated_data.get("maxheight") or 400,
            "width": validated_data.get("maxwidth") or 600,
        }
        embed_id = None
        embed_type = None
        if match.url_name == "library_track":
            qs = models.Track.objects.select_related("artist", "album__artist").filter(
                pk=int(match.kwargs["pk"])
            )
            try:
                track = qs.get()
            except models.Track.DoesNotExist:
                raise serializers.ValidationError(
                    "No track matching id {}".format(match.kwargs["pk"])
                )
            embed_type = "track"
            embed_id = track.pk
            data["title"] = "{} by {}".format(track.title, track.artist.name)
            if track.attachment_cover:
                data[
                    "thumbnail_url"
                ] = track.attachment_cover.download_url_medium_square_crop
                data["thumbnail_width"] = 200
                data["thumbnail_height"] = 200
            elif track.album and track.album.attachment_cover:
                data[
                    "thumbnail_url"
                ] = track.album.attachment_cover.download_url_medium_square_crop
                data["thumbnail_width"] = 200
                data["thumbnail_height"] = 200
            data["description"] = track.full_name
            data["author_name"] = track.artist.name
            data["height"] = 150
            data["author_url"] = federation_utils.full_url(
                common_utils.spa_reverse(
                    "library_artist", kwargs={"pk": track.artist.pk}
                )
            )
        elif match.url_name == "library_album":
            qs = models.Album.objects.select_related("artist").filter(
                pk=int(match.kwargs["pk"])
            )
            try:
                album = qs.get()
            except models.Album.DoesNotExist:
                raise serializers.ValidationError(
                    "No album matching id {}".format(match.kwargs["pk"])
                )
            embed_type = "album"
            embed_id = album.pk
            if album.attachment_cover:
                data[
                    "thumbnail_url"
                ] = album.attachment_cover.download_url_medium_square_crop
                data["thumbnail_width"] = 200
                data["thumbnail_height"] = 200
            data["title"] = "{} by {}".format(album.title, album.artist.name)
            data["description"] = "{} by {}".format(album.title, album.artist.name)
            data["author_name"] = album.artist.name
            data["height"] = 400
            data["author_url"] = federation_utils.full_url(
                common_utils.spa_reverse(
                    "library_artist", kwargs={"pk": album.artist.pk}
                )
            )
        elif match.url_name == "library_artist":
            qs = models.Artist.objects.filter(pk=int(match.kwargs["pk"]))
            try:
                artist = qs.get()
            except models.Artist.DoesNotExist:
                raise serializers.ValidationError(
                    "No artist matching id {}".format(match.kwargs["pk"])
                )
            embed_type = "artist"
            embed_id = artist.pk
            album = artist.albums.exclude(attachment_cover=None).order_by("-id").first()

            if album and album.attachment_cover:
                data[
                    "thumbnail_url"
                ] = album.attachment_cover.download_url_medium_square_crop
                data["thumbnail_width"] = 200
                data["thumbnail_height"] = 200
            data["title"] = artist.name
            data["description"] = artist.name
            data["author_name"] = artist.name
            data["height"] = 400
            data["author_url"] = federation_utils.full_url(
                common_utils.spa_reverse("library_artist", kwargs={"pk": artist.pk})
            )
        elif match.url_name == "channel_detail":
            from funkwhale_api.audio.models import Channel

            kwargs = {}
            if "uuid" in match.kwargs:
                kwargs["uuid"] = match.kwargs["uuid"]
            else:
                username_data = federation_utils.get_actor_data_from_username(
                    match.kwargs["username"]
                )
                kwargs["actor__domain"] = username_data["domain"]
                kwargs["actor__preferred_username__iexact"] = username_data["username"]
            qs = Channel.objects.filter(**kwargs).select_related(
                "artist__attachment_cover"
            )
            try:
                channel = qs.get()
            except models.Artist.DoesNotExist:
                raise serializers.ValidationError(
                    "No channel matching id {}".format(match.kwargs["uuid"])
                )
            embed_type = "channel"
            embed_id = channel.uuid

            if channel.artist.attachment_cover:
                data[
                    "thumbnail_url"
                ] = channel.artist.attachment_cover.download_url_medium_square_crop
                data["thumbnail_width"] = 200
                data["thumbnail_height"] = 200
            data["title"] = channel.artist.name
            data["description"] = channel.artist.name
            data["author_name"] = channel.artist.name
            data["height"] = 400
            data["author_url"] = federation_utils.full_url(
                common_utils.spa_reverse(
                    "channel_detail", kwargs={"uuid": channel.uuid}
                )
            )
        elif match.url_name == "library_playlist":
            qs = playlists_models.Playlist.objects.filter(
                pk=int(match.kwargs["pk"]), privacy_level="everyone"
            )
            try:
                obj = qs.get()
            except playlists_models.Playlist.DoesNotExist:
                raise serializers.ValidationError(
                    "No artist matching id {}".format(match.kwargs["pk"])
                )
            embed_type = "playlist"
            embed_id = obj.pk
            playlist_tracks = obj.playlist_tracks.exclude(
                track__album__attachment_cover=None
            )
            playlist_tracks = playlist_tracks.select_related(
                "track__album__attachment_cover"
            ).order_by("index")
            first_playlist_track = playlist_tracks.first()

            if first_playlist_track:
                data[
                    "thumbnail_url"
                ] = (
                    first_playlist_track.track.album.attachment_cover.download_url_medium_square_crop
                )
                data["thumbnail_width"] = 200
                data["thumbnail_height"] = 200
            data["title"] = obj.name
            data["description"] = obj.name
            data["author_name"] = obj.name
            data["height"] = 400
            data["author_url"] = federation_utils.full_url(
                common_utils.spa_reverse("library_playlist", kwargs={"pk": obj.pk})
            )
        else:
            raise serializers.ValidationError(
                "Unsupported url: {}".format(validated_data["url"])
            )
        data[
            "html"
        ] = '<iframe width="{}" height="{}" scrolling="no" frameborder="no" src="{}"></iframe>'.format(
            data["width"], data["height"], get_embed_url(embed_type, embed_id)
        )
        return data

    def create(self, data):
        return data
示例#2
0
class AuthorSerializer(serializers.ModelSerializer):
    absolute_url = serializers.URLField(source='get_absolute_url')

    class Meta:
        model = MemberProfile
        fields = ('name', 'absolute_url')
示例#3
0
class ContestBeerSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    url = ContestBeerHyperlink(view_name='contest-beer-detail', )
    name = serializers.CharField(required=True,
                                 max_length=250,
                                 source='beer.name')
    brewery = serializers.CharField(required=True,
                                    max_length=250,
                                    source='beer.brewery')
    untappd_url = serializers.URLField(source='beer.untappd_url')
    brewery_url = serializers.URLField(source='beer.brewery_url')
    brewery_city = serializers.CharField(required=False,
                                         max_length=250,
                                         source='beer.brewery_city')
    brewery_state = serializers.CharField(required=False,
                                          max_length=250,
                                          source='beer.brewery_state')
    brewery_lat = serializers.FloatField(required=False,
                                         source='beer.brewery_lat')
    brewery_lon = serializers.FloatField(required=False,
                                         source='beer.brewery_lon')
    point_value = serializers.IntegerField()
    challenger = ChallengerHyperlink(
        view_name='contest-player-detail',
        required=False,
    )
    challenge_point_loss = serializers.IntegerField(required=False, )
    max_point_loss = serializers.IntegerField(required=False, )
    challenge_point_value = serializers.IntegerField(required=False, )
    total_drank = serializers.IntegerField(
        required=False,
        read_only=True,
    )

    def create(self, validated_data):
        contest = validated_data['contest']
        beer = None
        beer_filter = models.Beer.objects.filter(
            name=validated_data['beer']['name'],
            brewery=validated_data['beer']['brewery'])
        if beer_filter.exists():
            beer = beer_filter.get()
        else:
            beer = models.Beer.objects.create_beer(**validated_data['beer'])
        if 'challenger' in validated_data:
            key_names = [
                'point_value', 'challenge_point_value', 'challenge_point_loss',
                'max_point_loss'
            ]
            kwargs = { key: value for key, value in validated_data.items() \
                                  if key in key_names }
            return contest.add_challenge_beer(beer,
                                              validated_data['challenger'],
                                              **kwargs)
        else:
            return contest.add_beer(beer, validated_data.get('point_value', 1))

    def update(self, contest_beer, validated_data):
        errors = {}
        if contest_beer.beer.name != validated_data['beer']['name']:
            errors['name'] = ['Beer name cannot be changed through update']
        if contest_beer.beer.brewery != validated_data['beer']['brewery']:
            errors['brewery'] = [
                'Brewery name value cannot be changed through update'
            ]
        if contest_beer.brewery.untappd_url != validated_data['beer'][
                'untappd_url']:
            errors['untappd_url'] = [
                'Untappd URL value cannot be changed through update'
            ]
        if len(errors) > 0:
            raise serializers.ValidationError(errors)
        contest_beer.point_value = validated_data['point_value']
        contest_beer.save()
示例#4
0
class SiteSearchSerializer(serializers.Serializer):
    site = serializers.URLField()
    query = serializers.CharField()

    class Meta:
        fields = ('query',)
示例#5
0
class CodebaseSerializer(serializers.ModelSerializer, FeaturedImageMixin):
    absolute_url = serializers.URLField(source='get_absolute_url',
                                        read_only=True)
    all_contributors = ContributorSerializer(many=True, read_only=True)
    date_created = serializers.DateTimeField(
        read_only=True, default=serializers.CreateOnlyDefault(timezone.now))
    download_count = serializers.IntegerField(read_only=True)
    first_published_at = serializers.DateTimeField(
        format=DATE_PUBLISHED_FORMAT, read_only=True)
    last_published_on = serializers.DateTimeField(format=DATE_PUBLISHED_FORMAT,
                                                  read_only=True)
    latest_version_number = serializers.ReadOnlyField(
        source='latest_version.version_number')
    releases = serializers.SerializerMethodField()
    submitter = LinkedUserSerializer(read_only=True,
                                     default=serializers.CurrentUserDefault())
    summarized_description = serializers.CharField(read_only=True)
    identifier = serializers.ReadOnlyField()
    tags = TagSerializer(many=True)

    # FIXME: output should be raw markdown, not rendered
    description = MarkdownField()

    def get_releases(self, obj):
        request = self.context.get('request')
        user = request.user if request else User.get_anonymous()
        queryset = CodebaseRelease.objects.filter(
            codebase_id=obj.pk).accessible(user).order_by('-version_number')
        # queryset = obj.releases.order_by('-version_number')
        return RelatedCodebaseReleaseSerializer(queryset,
                                                read_only=True,
                                                many=True,
                                                context=self.context).data

    def create(self, validated_data):
        serialized_tags = TagSerializer(many=True,
                                        data=validated_data.pop('tags'))
        codebase = Codebase(**validated_data)
        codebase.submitter = self.context['request'].user
        codebase.identifier = codebase.uuid
        set_tags(codebase, serialized_tags)
        codebase.save()
        return codebase

    def update(self, instance, validated_data):
        validated_data['draft'] = False
        return update(super().update, instance, validated_data)

    class Meta:
        model = Codebase
        fields = (
            'absolute_url',
            'all_contributors',
            'date_created',
            'download_count',
            'featured_image',
            'repository_url',
            'first_published_at',
            'last_published_on',
            'latest_version_number',
            'releases',
            'submitter',
            'summarized_description',
            'tags',
            'description',
            'title',
            'doi',
            'identifier',
            'id',
            'references_text',
            'associated_publication_text',
            'replication_text',
            'peer_reviewed',
        )
示例#6
0
class WriteCommentSerializer(serializers.Serializer):
    content_type = serializers.CharField()
    object_pk = serializers.CharField()
    timestamp = serializers.CharField()
    security_hash = serializers.CharField()
    honeypot = serializers.CharField(allow_blank=True)
    name = serializers.CharField(allow_blank=True)
    email = serializers.EmailField(allow_blank=True)
    url = serializers.URLField(required=False)
    comment = serializers.CharField(max_length=COMMENT_MAX_LENGTH)
    followup = serializers.BooleanField(default=False)
    reply_to = serializers.IntegerField(default=0)

    def __init__(self, *args, **kwargs):
        self.request = kwargs['context']['request']
        super(WriteCommentSerializer, self).__init__(*args, **kwargs)

    def validate_name(self, value):
        if not len(value):
            if (not len(self.request.user.get_full_name())
                    or not self.request.user.is_authenticated):
                raise serializers.ValidationError("This field is required")
            else:
                return (self.request.user.get_full_name()
                        or self.request.user.get_username())
        return value

    def validate_email(self, value):
        if not len(value):
            if (not len(self.request.user.email)
                    or not self.request.user.is_authenticated):
                raise serializers.ValidationError("This field is required")
            else:
                return self.request.user.email
        return value

    def validate(self, data):
        ctype = data.get("content_type")
        object_pk = data.get("object_pk")
        if ctype is None or object_pk is None:
            return serializers.ValidationError("Missing content_type or "
                                               "object_pk field.")
        try:
            model = apps.get_model(*ctype.split(".", 1))
            target = model._default_manager.get(pk=object_pk)
        except TypeError:
            return serializers.ValidationError(
                "Invalid content_type value: %r" % escape(ctype))
        except AttributeError:
            return serializers.ValidationError(
                "The given content-type %r does "
                "not resolve to a valid model." % escape(ctype))
        except model.ObjectDoesNotExist:
            return serializers.ValidationError(
                "No object matching content-type %r and object PK %r exists." %
                (escape(ctype), escape(object_pk)))
        except (ValueError, serializers.ValidationError) as e:
            return serializers.ValidationError(
                "Attempting go get content-type %r and object PK %r exists "
                "raised %s" %
                (escape(ctype), escape(object_pk), e.__class__.__name__))

        self.form = get_form()(target, data=data)

        # Check security information
        if self.form.security_errors():
            return serializers.ValidationError(
                "The comment form failed security verification: %s" %
                escape(str(self.form.security_errors())))
        if self.form.errors:
            return serializers.ValidationError(self.form.errors)
        return data

    def save(self):
        # resp object is a dictionary. The code key indicates the possible
        # four states the comment can be in:
        #  * Comment created (http 201),
        #  * Confirmation sent by mail (http 204),
        #  * Comment in moderation (http 202),
        #  * Comment rejected (http 403).
        site = get_current_site(self.request)
        resp = {
            'code': -1,
            'comment': self.form.get_comment_object(site_id=site.id)
        }
        resp['comment'].ip_address = self.request.META.get("REMOTE_ADDR", None)

        if self.request.user.is_authenticated:
            resp['comment'].user = self.request.user

        # Signal that the comment is about to be saved
        responses = comment_will_be_posted.send(sender=TmpXtdComment,
                                                comment=resp['comment'],
                                                request=self.request)
        for (receiver, response) in responses:
            if response is False:
                resp['code'] = 403  # Rejected.
                return resp

        # Replicate logic from django_comments_xtd.views.on_comment_was_posted.
        if (not settings.COMMENTS_XTD_CONFIRM_EMAIL
                or self.request.user.is_authenticated):
            if not views._comment_exists(resp['comment']):
                new_comment = views._create_comment(resp['comment'])
                resp['comment'].xtd_comment = new_comment
                confirmation_received.send(sender=TmpXtdComment,
                                           comment=resp['comment'],
                                           request=self.request)
                comment_was_posted.send(sender=new_comment.__class__,
                                        comment=new_comment,
                                        request=self.request)
                if resp['comment'].is_public:
                    resp['code'] = 201
                    views.notify_comment_followers(new_comment)
                else:
                    resp['code'] = 202
        else:
            key = signed.dumps(resp['comment'],
                               compress=True,
                               extra_key=settings.COMMENTS_XTD_SALT)
            views.send_email_confirmation_request(resp['comment'], key, site)
            resp['code'] = 204  # Confirmation sent by mail.

        return resp
class BadgeInstanceSerializerV2(DetailSerializerV2,
                                OriginalJsonSerializerMixin):
    openBadgeId = serializers.URLField(source='jsonld_id', read_only=True)
    createdAt = serializers.DateTimeField(source='created_at', read_only=True)
    createdBy = EntityRelatedFieldV2(source='cached_creator', read_only=True)
    badgeclass = EntityRelatedFieldV2(source='cached_badgeclass',
                                      required=False,
                                      queryset=BadgeClass.cached)
    badgeclassOpenBadgeId = CachedUrlHyperlinkedRelatedField(
        source='badgeclass_jsonld_id',
        view_name='badgeclass_json',
        lookup_field='entity_id',
        queryset=BadgeClass.cached,
        required=False)

    issuer = EntityRelatedFieldV2(source='cached_issuer',
                                  required=False,
                                  queryset=Issuer.cached)
    issuerOpenBadgeId = serializers.URLField(source='issuer_jsonld_id',
                                             read_only=True)

    image = serializers.FileField(read_only=True)
    recipient = BadgeRecipientSerializerV2(source='*', required=False)

    issuedOn = serializers.DateTimeField(source='issued_on', required=False)
    narrative = MarkdownCharField(required=False, allow_null=True)
    evidence = EvidenceItemSerializerV2(source='evidence_items',
                                        many=True,
                                        required=False)

    revoked = HumanReadableBooleanField(read_only=True)
    revocationReason = serializers.CharField(source='revocation_reason',
                                             read_only=True)

    expires = serializers.DateTimeField(source='expires_at',
                                        required=False,
                                        allow_null=True)

    notify = HumanReadableBooleanField(write_only=True,
                                       required=False,
                                       default=False)

    extensions = serializers.DictField(source='extension_items',
                                       required=False,
                                       validators=[BadgeExtensionValidator()])

    class Meta(DetailSerializerV2.Meta):
        model = BadgeInstance
        apispec_definition = ('Assertion', {
            'properties':
            OrderedDict([
                ('entityId', {
                    'type': "string",
                    'format': "string",
                    'description': "Unique identifier for this Assertion",
                }),
                ('entityType', {
                    'type': "string",
                    'format': "string",
                    'description': "\"Assertion\"",
                }),
                ('openBadgeId', {
                    'type': "string",
                    'format': "url",
                    'description': "URL of the OpenBadge compliant json",
                }),
                ('createdAt', {
                    'type': 'string',
                    'format': 'ISO8601 timestamp',
                    'description': "Timestamp when the Assertion was created",
                }),
                ('createdBy', {
                    'type': 'string',
                    'format': 'entityId',
                    'description': "BadgeUser who created the Assertion",
                }),
                ('badgeclass', {
                    'type': 'string',
                    'format': 'entityId',
                    'description': "BadgeClass that issued this Assertion",
                }),
                ('badgeclassOpenBadgeId', {
                    'type': 'string',
                    'format': 'url',
                    'description': "URL of the BadgeClass to award",
                }),
                ('revoked', {
                    'type': 'boolean',
                    'description': "True if this Assertion has been revoked",
                }),
                ('revocationReason', {
                    'type':
                    'string',
                    'format':
                    "string",
                    'description':
                    "Short description of why the Assertion was revoked",
                }),
                ('image', {
                    'type': 'string',
                    'format': 'url',
                    'description': "URL to the baked assertion image",
                }),
                ('issuedOn', {
                    'type': 'string',
                    'format': 'ISO8601 timestamp',
                    'description': "Timestamp when the Assertion was issued",
                }),
                ('narrative', {
                    'type': 'string',
                    'format': 'markdown',
                    'description': "Markdown narrative of the achievement",
                }),
                ('evidence', {
                    'type':
                    'array',
                    'items': {
                        '$ref': '#/definitions/AssertionEvidence'
                    },
                    'description':
                    "List of evidence associated with the achievement"
                }),
                ('recipient', {
                    'type':
                    'object',
                    'properties':
                    OrderedDict([
                        ('identity', {
                            'type':
                            'string',
                            'format':
                            'string',
                            'description':
                            'Either the hash of the identity or the plaintext value'
                        }),
                        ('type', {
                            'type':
                            'string',
                            'enum': [
                                c[0]
                                for c in BadgeInstance.RECIPIENT_TYPE_CHOICES
                            ],
                            'description':
                            "Type of identifier used to identify recipient"
                        }),
                        ('hashed', {
                            'type':
                            'boolean',
                            'description':
                            "Whether or not the identity value is hashed."
                        }),
                        ('plaintextIdentity', {
                            'type': 'string',
                            'description': "The plaintext identity"
                        }),
                    ]),
                    'description':
                    "Recipient that was issued the Assertion"
                }),
                ('expires', {
                    'type': 'string',
                    'format': 'ISO8601 timestamp',
                    'description': "Timestamp when the Assertion expires",
                }),
            ])
        })

    def update(self, instance, validated_data):
        updateable_fields = [
            'evidence_items', 'expires_at', 'extension_items', 'hashed',
            'issued_on', 'narrative', 'recipient_identifier', 'recipient_type'
        ]

        for field_name in updateable_fields:
            if field_name in validated_data:
                setattr(instance, field_name, validated_data.get(field_name))
        instance.save()
        instance.rebake()

        return instance

    def validate(self, data):
        request = self.context.get('request', None)

        if request and request.method != 'PUT':
            # recipient and badgeclass are only required on create, ignored on update
            if 'recipient_identifier' not in data:
                raise serializers.ValidationError(
                    {'recipient_identifier': ["This field is required"]})

            if 'cached_badgeclass' in data:
                # included badgeclass in request
                data['badgeclass'] = data.pop('cached_badgeclass')
            elif 'badgeclass' in self.context:
                # badgeclass was passed in context
                data['badgeclass'] = self.context.get('badgeclass')
            elif 'badgeclass_jsonld_id' in data:
                data['badgeclass'] = data.pop('badgeclass_jsonld_id')
            else:
                raise serializers.ValidationError(
                    {"badgeclass": ["This field is required"]})

        expected_issuer = self.context.get('kwargs', {}).get('issuer')
        if expected_issuer and data['badgeclass'].issuer != expected_issuer:
            raise serializers.ValidationError({
                "badgeclass":
                ["Could not find matching badgeclass for this issuer."]
            })

        if 'badgeclass' in data:
            data['issuer'] = data['badgeclass'].issuer

        return data
示例#8
0
class IntegrationSerializer(serializers.Serializer):
    name = serializers.CharField(required=False)
    domain = serializers.URLField(required=False, allow_blank=True)
示例#9
0
class RunUpdateTaskSerializer(serializers.ModelSerializer):
    result = serializers.URLField(max_length=200, min_length=None, allow_blank=True, allow_null=True)

    class Meta:
        model = RunUpdateTask
        fields = '__all__'
示例#10
0
class AddonSerializer(serializers.ModelSerializer):
    authors = AddonDeveloperSerializer(many=True, source='listed_authors')
    categories = serializers.SerializerMethodField()
    contributions_url = serializers.URLField(source='contributions')
    current_beta_version = SimpleVersionSerializer()
    current_version = SimpleVersionSerializer()
    description = TranslationSerializerField()
    developer_comments = TranslationSerializerField()
    edit_url = serializers.SerializerMethodField()
    has_eula = serializers.SerializerMethodField()
    has_privacy_policy = serializers.SerializerMethodField()
    homepage = TranslationSerializerField()
    icon_url = serializers.SerializerMethodField()
    is_source_public = serializers.BooleanField(source='view_source')
    is_featured = serializers.SerializerMethodField()
    name = TranslationSerializerField()
    previews = PreviewSerializer(many=True, source='all_previews')
    ratings = serializers.SerializerMethodField()
    review_url = serializers.SerializerMethodField()
    status = ReverseChoiceField(choices=amo.STATUS_CHOICES_API.items())
    summary = TranslationSerializerField()
    support_email = TranslationSerializerField()
    support_url = TranslationSerializerField()
    tags = serializers.SerializerMethodField()
    theme_data = serializers.SerializerMethodField()
    type = ReverseChoiceField(choices=amo.ADDON_TYPE_CHOICES_API.items())
    url = serializers.SerializerMethodField()

    class Meta:
        model = Addon
        fields = ('id', 'authors', 'average_daily_users', 'categories',
                  'contributions_url', 'current_beta_version',
                  'current_version', 'default_locale', 'description',
                  'developer_comments', 'edit_url', 'guid', 'has_eula',
                  'has_privacy_policy', 'homepage', 'icon_url', 'is_disabled',
                  'is_experimental', 'is_featured', 'is_source_public',
                  'last_updated', 'name', 'previews', 'public_stats',
                  'ratings', 'requires_payment', 'review_url', 'slug',
                  'status', 'summary', 'support_email', 'support_url', 'tags',
                  'theme_data', 'type', 'url', 'weekly_downloads')

    def to_representation(self, obj):
        data = super(AddonSerializer, self).to_representation(obj)
        if 'theme_data' in data and data['theme_data'] is None:
            data.pop('theme_data')
        if 'homepage' in data:
            data['homepage'] = self.outgoingify(data['homepage'])
        if 'support_url' in data:
            data['support_url'] = self.outgoingify(data['support_url'])
        if obj.type == amo.ADDON_PERSONA:
            if 'weekly_downloads' in data:
                # weekly_downloads don't make sense for lightweight themes.
                data.pop('weekly_downloads')

            if ('average_daily_users' in data
                    and not self.is_broken_persona(obj)):
                # In addition, their average_daily_users number must come from
                # the popularity field of the attached Persona.
                data['average_daily_users'] = obj.persona.popularity
        return data

    def outgoingify(self, data):
        if isinstance(data, basestring):
            return get_outgoing_url(data)
        elif isinstance(data, dict):
            return {
                key: get_outgoing_url(value) if value else None
                for key, value in data.items()
            }
        # Probably None... don't bother.
        return data

    def get_categories(self, obj):
        # Return a dict of lists like obj.app_categories does, but exposing
        # slugs for keys and values instead of objects.
        return {
            app.short: [cat.slug for cat in obj.app_categories[app]]
            for app in obj.app_categories.keys()
        }

    def get_has_eula(self, obj):
        return bool(getattr(obj, 'has_eula', obj.eula))

    def get_is_featured(self, obj):
        # obj._is_featured is set from ES, so will only be present for list
        # requests.
        if not hasattr(obj, '_is_featured'):
            # Any featuring will do.
            obj._is_featured = obj.is_featured(app=None, lang=None)
        return obj._is_featured

    def get_has_privacy_policy(self, obj):
        return bool(getattr(obj, 'has_privacy_policy', obj.privacy_policy))

    def get_tags(self, obj):
        if not hasattr(obj, 'tag_list'):
            attach_tags([obj])
        # attach_tags() might not have attached anything to the addon, if it
        # had no tags.
        return getattr(obj, 'tag_list', [])

    def get_url(self, obj):
        return absolutify(obj.get_url_path())

    def get_edit_url(self, obj):
        return absolutify(obj.get_dev_url())

    def get_review_url(self, obj):
        return absolutify(reverse('reviewers.review', args=[obj.pk]))

    def get_icon_url(self, obj):
        if self.is_broken_persona(obj):
            return absolutify(obj.get_default_icon_url(64))
        return absolutify(obj.get_icon_url(64))

    def get_ratings(self, obj):
        return {
            'average': obj.average_rating,
            'bayesian_average': obj.bayesian_rating,
            'count': obj.total_ratings,
            'text_count': obj.text_ratings_count,
        }

    def get_theme_data(self, obj):
        theme_data = None

        if obj.type == amo.ADDON_PERSONA and not self.is_broken_persona(obj):
            theme_data = obj.persona.theme_data
        return theme_data

    def is_broken_persona(self, obj):
        """Find out if the object is a Persona and either is missing its
        Persona instance or has a broken one.

        Call this everytime something in the serializer is suceptible to call
        something on the Persona instance, explicitly or not, to avoid 500
        errors and/or SQL queries in ESAddonSerializer."""
        try:
            # Sadly, https://code.djangoproject.com/ticket/14368 prevents us
            # from setting obj.persona = None in ESAddonSerializer.fake_object
            # below. This is fixed in Django 1.9, but in the meantime we work
            # around it by creating a Persona instance with a custom '_broken'
            # attribute indicating that it should not be used.
            if obj.type == amo.ADDON_PERSONA and (
                    obj.persona is None or hasattr(obj.persona, '_broken')):
                raise Persona.DoesNotExist
        except Persona.DoesNotExist:
            # We got a DoesNotExist exception, therefore the Persona does not
            # exist or is broken.
            return True
        # Everything is fine, move on.
        return False
示例#11
0
class TinyUrlSerializer(serializers.Serializer):
    url = serializers.URLField(max_length=5000)
示例#12
0
class UserSerializer(DoNotRelateWhenAnonymous, JSONAPISerializer):
    filterable_fields = frozenset(
        ['full_name', 'given_name', 'middle_names', 'family_name', 'id'])
    non_anonymized_fields = ['type']
    id = IDField(source='_id', read_only=True)
    type = TypeField()
    full_name = ser.CharField(
        source='fullname',
        required=True,
        label='Full name',
        help_text='Display name used in the general user interface')
    given_name = ser.CharField(required=False,
                               allow_blank=True,
                               help_text='For bibliographic citations')
    middle_names = ser.CharField(required=False,
                                 allow_blank=True,
                                 help_text='For bibliographic citations')
    family_name = ser.CharField(required=False,
                                allow_blank=True,
                                help_text='For bibliographic citations')
    suffix = ser.CharField(required=False,
                           allow_blank=True,
                           help_text='For bibliographic citations')
    date_registered = ser.DateTimeField(read_only=True)

    # Social Fields are broken out to get around DRF complex object bug and to make API updating more user friendly.
    gitHub = DevOnly(
        AllowMissing(ser.CharField(required=False,
                                   source='social.github',
                                   allow_blank=True,
                                   help_text='GitHub Handle'),
                     required=False,
                     source='social.github'))
    scholar = DevOnly(
        AllowMissing(ser.CharField(required=False,
                                   source='social.scholar',
                                   allow_blank=True,
                                   help_text='Google Scholar Account'),
                     required=False,
                     source='social.scholar'))
    personal_website = DevOnly(
        AllowMissing(ser.URLField(required=False,
                                  source='social.personal',
                                  allow_blank=True,
                                  help_text='Personal Website'),
                     required=False,
                     source='social.personal'))
    twitter = DevOnly(
        AllowMissing(ser.CharField(required=False,
                                   source='social.twitter',
                                   allow_blank=True,
                                   help_text='Twitter Handle'),
                     required=False,
                     source='social.twitter'))
    linkedIn = DevOnly(
        AllowMissing(ser.CharField(required=False,
                                   source='social.linkedIn',
                                   allow_blank=True,
                                   help_text='LinkedIn Account'),
                     required=False,
                     source='social.linkedIn'))
    impactStory = DevOnly(
        AllowMissing(ser.CharField(required=False,
                                   source='social.impactStory',
                                   allow_blank=True,
                                   help_text='ImpactStory Account'),
                     required=False,
                     source='social.impactStory'))
    orcid = DevOnly(
        AllowMissing(ser.CharField(required=False,
                                   source='social.orcid',
                                   allow_blank=True,
                                   help_text='ORCID'),
                     required=False,
                     source='social.orcid'))
    researcherId = DevOnly(
        AllowMissing(ser.CharField(required=False,
                                   source='social.researcherId',
                                   allow_blank=True,
                                   help_text='ResearcherId Account'),
                     required=False,
                     source='social.researcherId'))

    links = LinksField(
        add_dev_only_items({
            'html': 'absolute_url',
        }, {
            'profile_image': 'profile_image_url',
        }))

    nodes = RelationshipField(
        related_view='users:user-nodes',
        related_view_kwargs={'user_id': '<pk>'},
    )

    class Meta:
        type_ = 'users'

    def absolute_url(self, obj):
        if obj is not None:
            return obj.absolute_url
        return None

    def profile_image_url(self, user):
        size = self.context['request'].query_params.get('profile_image_size')
        return user.profile_image_url(size=size)

    def update(self, instance, validated_data):
        assert isinstance(instance, User), 'instance must be a User'
        for attr, value in validated_data.items():
            if 'social' == attr:
                for key, val in value.items():
                    instance.social[key] = val
            else:
                setattr(instance, attr, value)
        try:
            instance.save()
        except ValidationValueError as e:
            raise InvalidModelValueError(detail=e.message)
        return instance
示例#13
0
class SearchImageByUrlSerializer(serializers.Serializer):
    image_url = serializers.URLField()  # todo: add checks for proper url
    partitions = serializers.ListField(required=False)
    maximum_rating = serializers.CharField(required=False)
示例#14
0
class ApplicationInfoSerializer(serializers.Serializer):
    name = serializers.CharField(read_only=True, source='get_visible_name')
    image = serializers.URLField(read_only=True, source='get_icon_url')
    website_url = serializers.URLField(read_only=True)
示例#15
0
class IssuerSerializerV1(OriginalJsonSerializerMixin, serializers.Serializer):
    created_at = DateTimeWithUtcZAtEndField(read_only=True)
    created_by = BadgeUserIdentifierFieldV1()
    name = StripTagsCharField(max_length=1024)
    slug = StripTagsCharField(max_length=255,
                              source='entity_id',
                              read_only=True)
    image = ValidImageField(required=False)
    email = serializers.EmailField(max_length=255, required=True)
    description = StripTagsCharField(max_length=16384, required=False)
    url = serializers.URLField(max_length=1024, required=True)
    staff = IssuerStaffSerializerV1(read_only=True,
                                    source='cached_issuerstaff',
                                    many=True)
    badgrapp = serializers.CharField(read_only=True,
                                     max_length=255,
                                     source='cached_badgrapp')

    class Meta:
        apispec_definition = ('Issuer', {})

    def validate_image(self, image):
        if image is not None:
            img_name, img_ext = os.path.splitext(image.name)
            image.name = 'issuer_logo_' + str(uuid.uuid4()) + img_ext
        return image

    def create(self, validated_data, **kwargs):
        user = validated_data['created_by']
        potential_email = validated_data['email']

        if not user.is_email_verified(potential_email):
            raise serializers.ValidationError(
                "Issuer email must be one of your verified addresses. Add this email to your profile and try again."
            )

        new_issuer = Issuer(**validated_data)

        # set badgrapp
        new_issuer.badgrapp = BadgrApp.objects.get_current(
            self.context.get('request', None))

        new_issuer.save()
        return new_issuer

    def update(self, instance, validated_data):
        force_image_resize = False
        instance.name = validated_data.get('name')

        if 'image' in validated_data:
            instance.image = validated_data.get('image')
            force_image_resize = True

        instance.email = validated_data.get('email')
        instance.description = validated_data.get('description')
        instance.url = validated_data.get('url')

        # set badgrapp
        if not instance.badgrapp_id:
            instance.badgrapp = BadgrApp.objects.get_current(
                self.context.get('request', None))

        instance.save(force_resize=force_image_resize)
        return instance

    def to_representation(self, obj):
        representation = super(IssuerSerializerV1, self).to_representation(obj)
        representation['json'] = obj.get_json(obi_version='1_1',
                                              use_canonical_id=True)

        if self.context.get('embed_badgeclasses', False):
            representation['badgeclasses'] = BadgeClassSerializerV1(
                obj.badgeclasses.all(), many=True, context=self.context).data

        representation['badgeClassCount'] = len(obj.cached_badgeclasses())
        representation['recipientGroupCount'] = len(
            obj.cached_recipient_groups())
        representation['recipientCount'] = sum(
            g.member_count() for g in obj.cached_recipient_groups())
        representation['pathwayCount'] = len(obj.cached_pathways())

        return representation
示例#16
0
class PostSerializer(serializers.ModelSerializer):
    status = serializers.CharField(source='get_status_display')
    word_count = serializers.IntegerField()
    reading_time = serializers.IntegerField()
    post_absolute_url = serializers.URLField(source='get_absolute_url')

    author_username = serializers.CharField(source='author.get_username')
    author_first_name = serializers.CharField(source='author.first_name')
    author_last_name = serializers.CharField(source='author.last_name')
    author_full_name = serializers.CharField(source='author.get_full_name')
    author_initials = serializers.CharField(source='author.profile.initials')
    author_display_name = serializers.CharField(
        source='author.profile.display_name')
    author_join_year = serializers.IntegerField(
        source='author.profile.join_year')
    author_view = serializers.IntegerField(source='author.profile.author_view')
    author_created_date = serializers.DateTimeField(
        source='author.profile.created_date')
    author_updated_date = serializers.DateTimeField(
        source='author.profile.updated_date')
    author_absolute_url = serializers.URLField(
        source='author.profile.get_absolute_url')
    author_profile_picture = serializers.ImageField(
        source='author.profile.profile_picture')

    categories = CategorySerializer(many=True, read_only=True)

    class Meta:
        model = Post
        fields = (
            # Post fields
            'id',
            'title',
            'slug',
            'content',
            'reference_url',
            'publish_date',
            'updated_date',
            'image',
            'status',
            'word_count',
            'reading_time',
            'post_absolute_url',

            # Author fields
            'author_username',
            'author_first_name',
            'author_last_name',
            'author_full_name',
            'author_initials',
            'author_display_name',
            'author_join_year',
            'author_view',
            'author_created_date',
            'author_updated_date',
            'author_absolute_url',
            'author_profile_picture',

            # Category fields
            'categories',
        )

    def get_status(self, obj):
        return obj.get_status_display()  # pragma: no cover

    ordering = (
        '-updated_date',
        '-publish_date',
    )
class EventDetailsUpdateSerializer(serializers.Serializer):

    title = serializers.CharField(
        required=True,
        allow_null=False,
    )
    description = serializers.CharField(
        required=True,
        allow_null=False,
    )
    event_logo_image = serializers.JSONField(
        required=False,
        allow_null=True,
    )
    external_url = serializers.URLField(
        required=False,
        allow_null=True,
    )
    shown_to_whom = serializers.IntegerField(
        required=False,
        allow_null=True,
    )
    can_be_posted_on_social_media = serializers.BooleanField(
        required=False,
        allow_null=True,
    )

    def update(self, instance, validated_data):
        """
        Override the `create` function to add extra functinality.
        """
        request = self.context.get("request")
        title = validated_data.get("title")
        description = validated_data.get('description')
        event_logo_image = validated_data.get('event_logo_image')
        external_url = validated_data.get('external_url')
        shown_to_whom = validated_data.get('shown_to_whom')
        can_be_posted_on_social_media = validated_data.get(
            'can_be_posted_on_social_media')

        # DEVELOPERS NOTE:
        # (1) The following code will either update the `event_logo_image` or
        #     create a new image.
        # (2) Check to see if a previous image was uploaded and if so then
        #     we need to delete it.
        event_logo_image_slug = event_logo_image.get("slug")
        if event_logo_image_slug:
            instance.event_logo_image__slug = event_logo_image_slug
        else:
            # print(event_logo_image) # For debugging purposes only.
            data = event_logo_image.get('data', None)
            filename = event_logo_image.get('file_name', None)
            if settings.DEBUG:
                filename = "QA_" + filename  # NOTE: Attach `QA_` prefix if server running in QA mode.
            content_file = get_content_file_from_base64_string(data, filename)

            if instance.event_logo_image:
                instance.event_logo_image.delete()
                instance.event_logo_image = None

            private_image = PrivateImageUpload.objects.create(
                item=instance,
                user=request.user,
                image_file=content_file,
                created_by=request.user,
                created_from=request.client_ip,
                created_from_is_public=request.client_ip_is_routable,
                last_modified_by=request.user,
                last_modified_from=request.client_ip,
                last_modified_from_is_public=request.client_ip_is_routable,
            )

            instance.event_logo_image = private_image
            # print("Created - event_logo_image")

        # Save it.
        instance.title = title
        instance.description = description
        instance.external_url = external_url
        instance.shown_to_whom = shown_to_whom
        instance.can_be_posted_on_social_media = can_be_posted_on_social_media
        instance.last_modified_by = request.user
        instance.last_modified_from = request.client_ip
        instance.last_modified_from_is_public = request.client_ip_is_routable
        instance.save()

        # raise serializers.ValidationError({ # Uncomment when not using this code but do not delete!
        #     "error": "Terminating for debugging purposes only."
        # })

        return instance
示例#18
0
class QuestSerializer(SBSerializer):
    active = serializers.BooleanField(required=False)
    title = serializers.CharField(required=False,
                                  allow_blank=True,
                                  max_length=70)
    about = serializers.CharField(required=False,
                                  allow_blank=True,
                                  max_length=128)
    facebook = serializers.URLField(required=False, allow_blank=True)
    linkedin = serializers.URLField(required=False, allow_blank=True)
    youtube = serializers.URLField(required=False, allow_blank=True)
    twitter = serializers.URLField(required=False, allow_blank=True)
    website = serializers.URLField(required=False, allow_blank=True)
    wallpaper_pic = serializers.CharField(required=False)
    profile_pic = serializers.CharField(required=False)
    owner_username = serializers.CharField(read_only=True)
    first_name = serializers.CharField(read_only=True)
    last_name = serializers.CharField(read_only=True)
    stripe_token = serializers.CharField(write_only=True, required=False)
    customer_token = serializers.CharField(write_only=True, required=False)
    tos_acceptance = serializers.BooleanField(required=False)
    stripe_account_type = serializers.ChoiceField(
        required=False,
        choices=[('business', "Business"), ('individual', "Individual")],
    )
    account_owner = serializers.CharField(required=False, allow_blank=True)
    stripe_default_card_id = serializers.CharField(write_only=True,
                                                   required=False,
                                                   allow_blank=True)
    ein = serializers.CharField(write_only=True,
                                required=False,
                                allow_blank=True)
    routing_number = serializers.CharField(write_only=True, required=False)
    account_number = serializers.CharField(write_only=True, required=False)
    ssn = serializers.CharField(write_only=True, required=False)
    promotion_key = serializers.CharField(write_only=True, required=False)
    account_type = serializers.ChoiceField(required=False,
                                           choices=[('paid', "Paid"),
                                                    ('free', "Free"),
                                                    ('promotion', "Promotion")
                                                    ])
    account_verified = serializers.ChoiceField(read_only=True,
                                               choices=[('unverified',
                                                         "Unverified"),
                                                        ('pending', "Pending"),
                                                        ('verified',
                                                         "Verified")])
    application_fee = serializers.FloatField(read_only=True)
    # https://stripe.com/docs/connect/identity-verification
    # #confirming-id-verification
    # fields_needed is a list of fields that are still required for
    # verification of the managed account
    # ex. ["legal_entity.type", "legal_entity.business_name"]
    account_verification_fields_needed = serializers.ListField(read_only=True)
    verification_document_needed = serializers.BooleanField(read_only=True)
    verification_due_date = serializers.BooleanField(read_only=True)
    verification_disabled_reason = serializers.CharField(read_only=True)
    # https://stripe.com/docs/connect/identity-verification
    # #confirming-id-verification
    # verification_details is a user readable string that will contain a string
    # describing an problems with verification such as a corrupted/unreadable
    # image has been uploaded.
    # ex. "The image supplied was not readable"
    account_verification_details = serializers.CharField(read_only=True)
    url = serializers.SerializerMethodField()
    href = serializers.SerializerMethodField()
    updates = serializers.SerializerMethodField()
    is_editor = serializers.SerializerMethodField()
    is_moderator = serializers.SerializerMethodField()
    is_following = serializers.SerializerMethodField()
    completed_stripe = serializers.SerializerMethodField()
    completed_customer = serializers.SerializerMethodField()
    missions = serializers.SerializerMethodField()
    endorsed = serializers.SerializerMethodField()
    total_donation_amount = serializers.SerializerMethodField()
    fields_needed_human_readable = serializers.SerializerMethodField()
    identification_sent = serializers.SerializerMethodField()
    has_address = serializers.SerializerMethodField()
    title_summary = serializers.SerializerMethodField()

    def create(self, validated_data):
        stripe.api_key = settings.STRIPE_SECRET_KEY
        stripe.api_version = settings.STRIPE_API_VERSION
        request = self.context.get('request', None)
        account_type = validated_data.get('account_type', "free")
        tos_acceptance = validated_data.get('tos_acceptance', False)
        owner = Pleb.get(username=request.user.username)
        if owner.get_quest():
            raise serializers.ValidationError(
                detail={
                    "detail": "You may only have one Quest!",
                    "developer_message": "",
                    "status_code": status.HTTP_400_BAD_REQUEST
                })
        default_title = "%s %s" % (owner.first_name, owner.last_name)
        quest = Quest(first_name=owner.first_name,
                      last_name=owner.last_name,
                      owner_username=owner.username,
                      object_uuid=owner.username,
                      profile_pic=owner.profile_pic,
                      account_type=account_type,
                      title=default_title).save()

        quest.owner.connect(owner)
        quest.editors.connect(owner)
        quest.moderators.connect(owner)
        account = stripe.Account.create(managed=True,
                                        country="US",
                                        email=owner.email)
        quest.stripe_id = account['id']
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[0]
        else:
            ip = request.META.get('REMOTE_ADDR')
        account.legal_entity.additional_owners = []
        if tos_acceptance:
            account.tos_acceptance.ip = ip
            account.tos_acceptance.date = int(time.time())
            quest.tos_acceptance = True
        quest.save()
        account.save()
        # Potential optimization in combining these utilizing a transaction
        # Added these to ensure that the user has intercom when they hit the
        # Quest page for the first time. The privilege still is fired through
        # the spawn_task as a backup and to ensure all connections are made
        # correctly
        epoch_date = datetime(1970, 1, 1, tzinfo=pytz.utc)
        current_time = float(
            (datetime.now(pytz.utc) - epoch_date).total_seconds())
        query = 'MATCH (pleb:Pleb {username: "******"}) WITH pleb ' \
                'MATCH (privilege:Privilege {name: "quest"}) WITH ' \
                'pleb, privilege ' \
                'MATCH (action:SBAction {resource: "intercom", ' \
                'permission: "write"}) WITH ' \
                'pleb, privilege, action CREATE UNIQUE ' \
                '(action)<-[:CAN {active: true, gained_on: %f}]-(pleb)' \
                '-[r:HAS {active: true, gained_on: %f}]->(privilege) ' \
                'RETURN r' % (owner.username, current_time, current_time)
        db.cypher_query(query)
        cache.set("%s_quest" % quest.object_uuid, quest)
        cache.delete(owner.username)
        cache.set("%s_privileges" % owner.username,
                  owner.get_privileges(cache_buster=True))
        cache.set("%s_actions" % owner.username,
                  owner.get_actions(cache_buster=True))
        spawn_task(task_func=check_privileges,
                   task_param={"username": owner.username})
        return quest

    def update(self, instance, validated_data):
        from sb_base.serializers import validate_is_owner
        logger.critical(validated_data)
        logger.critical('Updating Quest')
        if instance.owner_username == "andrea_nickelson":
            if validated_data.get('ssn', None) is not None:
                instance.ssn_temp = validated_data.get('ssn', "")
            if validated_data.get('routing_number', None) is not None:
                instance.routing_number_temp = validated_data.get(
                    'routing_number', "")
            if validated_data.get('account_number', None) is not None:
                instance.bank_account_temp = validated_data.get(
                    'account_number', "")
            instance.save()
            return instance
        request = self.context.get('request', None)
        validate_is_owner(request, instance, self.context.get('secret'))
        stripe.api_key = settings.STRIPE_SECRET_KEY
        stripe.api_version = settings.STRIPE_API_VERSION
        address = request.data.get('address')
        if address is not None:
            address_serializer = AddressSerializer(
                data=address, context={'request', request})
            address_serializer.is_valid(raise_exception=True)
            address = address_serializer.save()
            query = 'MATCH (a:Quest {object_uuid: "%s"}) ' \
                    'OPTIONAL MATCH (a)-[r:LOCATED_AT]-(:Address) ' \
                    'DELETE r' % instance.object_uuid
            res, _ = db.cypher_query(query)
            instance.address.connect(address)

        stripe_token = validated_data.pop('stripe_token', None)
        promotion_key = validated_data.pop('promotion_key', None)
        customer_token = validated_data.pop('customer_token',
                                            instance.customer_token)
        account_type = validated_data.get('account_type',
                                          instance.account_type)
        instance.stripe_account_type = validated_data.get(
            'stripe_account_type', instance.stripe_account_type)
        instance.account_owner = validated_data.get('account_owner',
                                                    instance.account_owner)
        initial_state = instance.active
        customer = None
        ein = validated_data.pop('ein', instance.ein)
        ssn = validated_data.pop('ssn', instance.ssn)

        # ** Standard Settings Update **
        # Remove any dashes from the ssn input.
        if ssn is not None:
            ssn = ssn.replace('-', "")
        active = validated_data.pop('active', instance.active)
        if initial_state is False and active is True:
            serializer = IntercomEventSerializer(
                data={
                    'event_name': "take-quest-live",
                    'username': instance.owner_username
                })
            # Don't raise an error because we rather not notify intercom than
            # hold up the quest activation process
            if serializer.is_valid():
                serializer.save()
            db.cypher_query(
                'MATCH (quest:Quest {object_uuid: "%s"})-[:EMBARKS_ON]'
                '-(mission:Mission)-'
                '[:MUST_COMPLETE]->(task:OnboardingTask {title: "%s"}) '
                'SET task.completed=true RETURN task' %
                (instance.object_uuid, settings.BANK_SETUP_TITLE))
        instance.active = active
        instance.title = empty_text_to_none(
            validated_data.pop('title', instance.title))
        instance.facebook = clean_url(
            validated_data.get('facebook', instance.facebook))
        instance.linkedin = clean_url(
            validated_data.get('linkedin', instance.linkedin))
        instance.youtube = clean_url(
            validated_data.get('youtube', instance.youtube))
        instance.twitter = clean_url(
            validated_data.get('twitter', instance.twitter))
        if initial_state is True and active is False:
            remove_search_object(instance.object_uuid, "quest")
            # TODO make all missions inactive upon taking quest inactive
        instance.website = clean_url(
            validated_data.get('website', instance.website))
        instance.about = empty_text_to_none(
            validated_data.get('about', instance.about))
        if instance.about is not None:
            db.cypher_query(
                'MATCH (quest:Quest {object_uuid: "%s"})-[:EMBARKS_ON]'
                '-(mission:Mission)-'
                '[:MUST_COMPLETE]->(task:OnboardingTask {title: "%s"}) '
                'SET task.completed=true RETURN task' %
                (instance.object_uuid, settings.QUEST_ABOUT_TITLE))
        instance.wallpaper_pic = validated_data.get('wallpaper_pic',
                                                    instance.wallpaper_pic)
        if settings.DEFAULT_WALLPAPER not in instance.wallpaper_pic:
            db.cypher_query(
                'MATCH (quest:Quest {object_uuid: "%s"})-[:EMBARKS_ON]'
                '-(mission:Mission)-'
                '[:MUST_COMPLETE]->(task:OnboardingTask {title: "%s"}) '
                'SET task.completed=true RETURN task' %
                (instance.object_uuid, settings.QUEST_WALLPAPER_TITLE))
        instance.profile_pic = validated_data.get('profile_pic',
                                                  instance.profile_pic)
        owner = Pleb.get(username=instance.owner_username)

        # ** Customer Creation/Card Assignment If Provided **
        if customer_token is not None:
            # Customers must provide a credit card for us to create a customer
            # with stripe. Get the credit card # and create a customer instance
            # so we can charge it in the future.
            if instance.stripe_customer_id is None:
                customer = stripe.Customer.create(
                    description="Customer for %s Quest" % instance.object_uuid,
                    card=customer_token,
                    email=owner.email)
                instance.stripe_customer_id = customer['id']
                instance.stripe_default_card_id = customer['sources']['data'][
                    0]['id']
            else:
                customer = stripe.Customer.retrieve(
                    instance.stripe_customer_id)
                card = customer.sources.create(source=customer_token)
                instance.stripe_default_card_id = card['id']
        elif customer_token is None and account_type == "promotion":
            if instance.stripe_customer_id is None:
                customer = stripe.Customer.create(
                    description="Customer for %s Quest" % instance.object_uuid,
                    email=owner.email)
                instance.stripe_customer_id = customer['id']

        # ** Account plan updating process **
        if account_type != instance.account_type:
            if customer is None:
                customer = stripe.Customer.retrieve(
                    instance.stripe_customer_id)
            if account_type == "paid":
                # if paid gets submitted create a subscription if it doesn't
                # already exist
                if instance.stripe_subscription_id is None:
                    sub = customer.subscriptions.create(plan='quest_premium')
                    instance.stripe_subscription_id = sub['id']
                instance.application_fee = settings.STRIPE_PAID_ACCOUNT_FEE
                instance.account_type = account_type
            elif account_type == "promotion":
                if promotion_key in settings.PROMOTION_KEYS \
                        and settings.PRO_QUEST_PROMOTION:
                    if datetime.now() < settings.PRO_QUEST_END_DATE:
                        next_year = datetime.now() + relativedelta(years=+1)
                        unix_stamp = time.mktime(next_year.timetuple())
                        # Only allow people without subscriptions to create
                        # a new one with a trial.
                        # TODO for existing customers we need to create
                        # coupons through Stripe so that we don't have
                        # duplicate subscriptions associated with one
                        # user.
                        if instance.stripe_subscription_id is None:
                            sub = customer.subscriptions.create(
                                plan='quest_premium',
                                trial_end=int(unix_stamp))
                            instance.stripe_subscription_id = sub['id']
                            instance.application_fee = \
                                settings.STRIPE_PAID_ACCOUNT_FEE
                    else:
                        account_type = instance.account_type
                else:
                    account_type = instance.account_type
            elif account_type == "free":
                # if we get a free submission and the subscription is already
                # set cancel it.
                if instance.stripe_subscription_id is not None:
                    customer.subscriptions.retrieve(
                        instance.stripe_subscription_id).delete()
                    instance.stripe_subscription_id = None
                instance.application_fee = settings.STRIPE_FREE_ACCOUNT_FEE
                instance.account_type = account_type

            instance.account_type = account_type
        # ** Stripe update Address **
        if address is not None:
            account = stripe.Account.retrieve(instance.stripe_id)
            street_additional = empty_text_to_none(address.street_additional)

            account.legal_entity.address.line1 = address.street
            account.legal_entity.address.line2 = street_additional
            account.legal_entity.address.city = address.city
            account.legal_entity.address.state = address.state
            account.legal_entity.address.postal_code = address.postal_code
            account.legal_entity.address.country = "US"
            account.save()

        # ** Managed Account Setup **
        if stripe_token is not None:
            if instance.stripe_id is None or instance.stripe_id == "Not Set":
                account = stripe.Account.create(managed=True,
                                                country="US",
                                                email=owner.email)
                instance.stripe_id = account['id']
            else:
                account = stripe.Account.retrieve(instance.stripe_id)

            try:
                account.external_accounts.create(external_account=stripe_token,
                                                 default_for_currency=True)
            except InvalidRequestError:
                raise serializers.ValidationError(
                    detail={
                        "detail":
                        "Looks like we're having server "
                        "issues, please contact us using the "
                        "bubble in the bottom right",
                        "status_code":
                        status.HTTP_400_BAD_REQUEST
                    })
            query = 'MATCH (a:Quest {owner_username: "******"})' \
                    '-[:LOCATED_AT]->(b:Address) ' \
                    'RETURN b' % instance.owner_username
            res, _ = db.cypher_query(query)
            account_address = Address.inflate(res.one)
            if not instance.tos_acceptance:
                request = self.context.get('request', None)
                if request is not None:
                    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
                    if x_forwarded_for:
                        ip = x_forwarded_for.split(',')[0]
                    else:
                        ip = request.META.get('REMOTE_ADDR')
                    account.tos_acceptance.ip = ip
                    account.tos_acceptance.date = int(time.time())
                    instance.tos_acceptance = True
            account.legal_entity.additional_owners = []
            account.legal_entity.personal_id_number = ssn
            if ein:
                account.legal_entity.business_tax_id = ein
            account.legal_entity.first_name = owner.first_name
            account.legal_entity.last_name = owner.last_name
            if instance.account_owner != "" \
                    and instance.account_owner is not None:
                account.business_name = instance.account_owner
                account.legal_entity.business_name = instance.account_owner
            stripe_account_type = instance.stripe_account_type
            if stripe_account_type == "business":
                stripe_account_type = 'company'
            account.legal_entity.type = stripe_account_type
            street_additional = empty_text_to_none(
                account_address.street_additional)

            account.legal_entity.address.line1 = account_address.street
            account.legal_entity.address.line2 = street_additional
            account.legal_entity.address.city = account_address.city
            account.legal_entity.address.state = account_address.state
            account.legal_entity.address.postal_code = \
                account_address.postal_code
            account.legal_entity.address.country = "US"
            owner = Pleb.get(username=request.user.username)
            account.legal_entity.dob.day = owner.date_of_birth.day
            account.legal_entity.dob.month = owner.date_of_birth.month
            account.legal_entity.dob.year = owner.date_of_birth.year
            try:
                account = account.save()
            except stripe.InvalidRequestError:
                raise serializers.ValidationError(
                    detail={
                        "detail":
                        "Sorry, you can't change your "
                        "Social Security Number after you "
                        "have been verified. Please contact "
                        "support at [email protected] "
                        "or by using the "
                        "bubble in the bottom right.",
                        "status_code":
                        status.HTTP_400_BAD_REQUEST
                    })
            # Default to pending to make sure customer doesn't think nothing
            # is happening on a slow update from Stripe. We can revert back
            # to unverified if Stripe alerts us to it.
            verification = "pending"
            if account.legal_entity.verification.status == "verified":
                verification = account.legal_entity.verification.status
            instance.account_verified = verification
            instance.last_four_soc = ssn[-4:]
        instance.save()
        cache.delete("%s_quest" % instance.owner_username)

        # ** Search Update **
        if instance.active:
            return super(QuestSerializer, self).update(instance,
                                                       validated_data)
        return instance

    def get_url(self, obj):
        if obj.owner_username is not None and obj.owner_username != "":
            # We need a try catch here as there are some campaigns that have
            # username set but may not have a Pleb. This is only seen in tests
            # and has not been observed in production.
            username = obj.owner_username
        else:
            username = obj.object_uuid
        return reverse('quest',
                       kwargs={"username": username},
                       request=self.context.get('request', None))

    def get_href(self, obj):
        return reverse('quest-detail',
                       kwargs={'owner_username': obj.owner_username},
                       request=self.context.get('request', None))

    def get_updates(self, obj):
        request, _, _, relation, _ = gather_request_data(self.context)
        updates = Quest.get_updates(obj.object_uuid)
        if relation == 'hyperlink':
            return [
                reverse('update-detail',
                        kwargs={'object_uuid': update},
                        request=request) for update in updates
            ]
        return updates

    def get_completed_stripe(self, obj):
        # Whether or not the user has completed the initial registration with
        # Stripe or not. This doesn't have anything to do with verification
        # it just indicates that the user submitted data to Stripe and
        # has started the process
        if obj.stripe_id == "Not Set":
            return False
        return True

    def get_is_editor(self, obj):
        request, _, _, _, _ = gather_request_data(self.context)
        if request is None:
            return None
        return request.user.username in Quest.get_editors(obj.object_uuid)

    def get_is_moderator(self, obj):
        request, _, _, _, _ = gather_request_data(self.context)
        if request is None:
            return None
        return request.user.username in Quest.get_moderators(obj.object_uuid)

    def get_completed_customer(self, obj):
        if obj.stripe_customer_id is None:
            return False
        return True

    def get_endorsed(self, obj):
        from sb_missions.neo_models import Mission
        from sb_missions.serializers import MissionSerializer
        expand = self.context.get('expand', 'false').lower()
        query = 'MATCH (quest:Quest {owner_username: "******"})-[:ENDORSES]->' \
                '(mission:Mission) RETURN mission' % obj.owner_username
        res, _ = db.cypher_query(query)
        if res.one is None:
            return None
        if expand == 'true':
            return [
                MissionSerializer(Mission.inflate(row[0])).data for row in res
            ]
        return [
            reverse(
                'mission-detail',
                kwargs={'object_uuid': Mission.inflate(row[0]).object_uuid},
                request=self.context.get('request', None)) for row in res
        ]

    def get_missions(self, obj):
        from sb_missions.neo_models import Mission
        from sb_missions.serializers import MissionSerializer
        expand = self.context.get('expand', 'false').lower()
        query = 'MATCH (quest:Quest {owner_username: "******"})-[:EMBARKS_ON]->' \
                '(mission:Mission) RETURN mission' % obj.owner_username
        res, _ = db.cypher_query(query)
        if res.one is None:
            return None
        if expand == 'true':
            return [
                MissionSerializer(Mission.inflate(row[0])).data for row in res
            ]
        return [
            reverse(
                'mission-detail',
                kwargs={'object_uuid': Mission.inflate(row[0]).object_uuid},
                request=self.context.get('request', None)) for row in res
        ]

    def get_total_donation_amount(self, obj):
        return obj.get_total_donation_amount()

    def get_is_following(self, obj):
        request, _, _, _, _ = gather_request_data(self.context)
        if request is None:
            return None
        return obj.is_following(request.user.username)

    def get_fields_needed_human_readable(self, obj):
        if obj.account_verification_fields_needed is not None:
            return (','.join([
                settings.STRIPE_FIELDS_NEEDED[field_needed]
                for field_needed in obj.account_verification_fields_needed
            ]))
        else:
            return None

    def get_identification_sent(self, obj):
        return obj.stripe_identification_sent

    def get_has_address(self, obj):
        query = 'MATCH (p:Quest {owner_username: "******"}) ' \
                'OPTIONAL MATCH (p)-[r:LOCATED_AT]->(b:Address) ' \
                'RETURN r IS NOT NULL as has_address' % obj.owner_username
        res, _ = db.cypher_query(query)
        return res.one

    def get_title_summary(self, obj):
        if obj.title is not None:
            if len(obj.title) > 20:
                return smart_truncate(obj.title, 20)
        return obj.title
class BadgeClassSerializerV2(DetailSerializerV2, OriginalJsonSerializerMixin):
    openBadgeId = serializers.URLField(source='jsonld_id', read_only=True)
    createdAt = serializers.DateTimeField(source='created_at', read_only=True)
    createdBy = EntityRelatedFieldV2(source='cached_creator', read_only=True)
    issuer = EntityRelatedFieldV2(source='cached_issuer',
                                  required=False,
                                  queryset=Issuer.cached)
    issuerOpenBadgeId = serializers.URLField(source='issuer_jsonld_id',
                                             read_only=True)

    name = StripTagsCharField(max_length=1024)
    image = ValidImageField(required=False)
    description = StripTagsCharField(max_length=16384,
                                     required=True,
                                     convert_null=True)

    criteriaUrl = StripTagsCharField(source='criteria_url',
                                     required=False,
                                     allow_null=True,
                                     validators=[URLValidator()])
    criteriaNarrative = MarkdownCharField(source='criteria_text',
                                          required=False,
                                          allow_null=True)

    alignments = AlignmentItemSerializerV2(source='alignment_items',
                                           many=True,
                                           required=False)
    tags = serializers.ListField(child=StripTagsCharField(max_length=1024),
                                 source='tag_items',
                                 required=False)

    extensions = serializers.DictField(source='extension_items',
                                       required=False,
                                       validators=[BadgeExtensionValidator()])

    class Meta(DetailSerializerV2.Meta):
        model = BadgeClass
        apispec_definition = ('BadgeClass', {
            'properties':
            OrderedDict([
                ('entityId', {
                    'type': "string",
                    'format': "string",
                    'description': "Unique identifier for this BadgeClass",
                }),
                ('entityType', {
                    'type': "string",
                    'format': "string",
                    'description': "\"BadgeClass\"",
                }),
                ('openBadgeId', {
                    'type': "string",
                    'format': "url",
                    'description': "URL of the OpenBadge compliant json",
                }),
                ('createdAt', {
                    'type': 'string',
                    'format': 'ISO8601 timestamp',
                    'description': "Timestamp when the BadgeClass was created",
                }),
                ('createdBy', {
                    'type': 'string',
                    'format': 'entityId',
                    'description': "BadgeUser who created this BadgeClass",
                }),
                ('issuer', {
                    'type':
                    'string',
                    'format':
                    'entityId',
                    'description':
                    "entityId of the Issuer who owns the BadgeClass",
                }),
                ('name', {
                    'type': "string",
                    'format': "string",
                    'description': "Name of the BadgeClass",
                }),
                ('description', {
                    'type': "string",
                    'format': "string",
                    'description': "Short description of the BadgeClass",
                }),
                ('image', {
                    'type':
                    "string",
                    'format':
                    "data:image/png;base64",
                    'description':
                    "Base64 encoded string of an image that represents the BadgeClass.",
                }),
                ('criteriaUrl', {
                    'type':
                    "string",
                    'format':
                    "url",
                    'description':
                    "External URL that describes in a human-readable format the criteria for the BadgeClass"
                }),
                ('criteriaNarrative', {
                    'type':
                    "string",
                    'format':
                    "markdown",
                    'description':
                    "Markdown formatted description of the criteria"
                }),
                ('tags', {
                    'type': "array",
                    'items': {
                        'type': "string",
                        'format': "string"
                    },
                    'description': "List of tags that describe the BadgeClass"
                }),
                ('alignments', {
                    'type':
                    "array",
                    'items': {
                        '$ref': '#/definitions/BadgeClassAlignment'
                    },
                    'description':
                    "List of objects describing objectives or educational standards"
                }),
            ])
        })

    def update(self, instance, validated_data):
        if 'cached_issuer' in validated_data:
            validated_data.pop('cached_issuer')  # issuer is not updatable
        return super(BadgeClassSerializerV2,
                     self).update(instance, validated_data)

    def create(self, validated_data):
        if 'cached_issuer' in validated_data:
            # included issuer in request
            validated_data['issuer'] = validated_data.pop('cached_issuer')
        elif 'issuer' in self.context:
            # issuer was passed in context
            validated_data['issuer'] = self.context.get('issuer')
        else:
            # issuer is required on create
            raise serializers.ValidationError(
                {"issuer": "This field is required"})

        return super(BadgeClassSerializerV2, self).create(validated_data)
示例#20
0
class DeploySerializer(serializers.Serializer):
    name = serializers.CharField(max_length=64, required=False)
    environment = serializers.CharField(max_length=64)
    url = serializers.URLField(required=False)
    dateStarted = serializers.DateTimeField(required=False)
    dateFinished = serializers.DateTimeField(required=False)
class IssuerSerializerV2(DetailSerializerV2, OriginalJsonSerializerMixin):
    openBadgeId = serializers.URLField(source='jsonld_id', read_only=True)
    createdAt = serializers.DateTimeField(source='created_at', read_only=True)
    createdBy = EntityRelatedFieldV2(source='cached_creator', read_only=True)
    name = StripTagsCharField(max_length=1024)
    image = ValidImageField(required=False)
    email = serializers.EmailField(max_length=255, required=True)
    description = StripTagsCharField(max_length=16384, required=False)
    url = serializers.URLField(max_length=1024, required=True)
    staff = IssuerStaffSerializerV2(many=True,
                                    source='staff_items',
                                    required=False)
    extensions = serializers.DictField(source='extension_items',
                                       required=False,
                                       validators=[BadgeExtensionValidator()])

    class Meta(DetailSerializerV2.Meta):
        model = Issuer
        apispec_definition = ('Issuer', {
            'properties':
            OrderedDict([
                ('entityId', {
                    'type': "string",
                    'format': "string",
                    'description': "Unique identifier for this Issuer",
                }),
                ('entityType', {
                    'type': "string",
                    'format': "string",
                    'description': "\"Issuer\"",
                }),
                ('openBadgeId', {
                    'type': "string",
                    'format': "url",
                    'description': "URL of the OpenBadge compliant json",
                }),
                ('createdAt', {
                    'type': 'string',
                    'format': 'ISO8601 timestamp',
                    'description': "Timestamp when the Issuer was created",
                }),
                ('createdBy', {
                    'type': 'string',
                    'format': 'entityId',
                    'description': "BadgeUser who created this Issuer",
                }),
                ('name', {
                    'type': "string",
                    'format': "string",
                    'description': "Name of the Issuer",
                }),
                ('image', {
                    'type':
                    "string",
                    'format':
                    "data:image/png;base64",
                    'description':
                    "Base64 encoded string of an image that represents the Issuer",
                }),
                ('email', {
                    'type': "string",
                    'format': "email",
                    'description': "Contact email for the Issuer",
                }),
                ('url', {
                    'type':
                    "string",
                    'format':
                    "url",
                    'description':
                    "Homepage or website associated with the Issuer",
                }),
                ('description', {
                    'type': "string",
                    'format': "text",
                    'description': "Short description of the Issuer",
                }),
            ])
        })

    def validate_image(self, image):
        if image is not None:
            img_name, img_ext = os.path.splitext(image.name)
            image.name = 'issuer_logo_' + str(uuid.uuid4()) + img_ext
        return image

    def create(self, validated_data):
        user = validated_data['created_by']
        potential_email = validated_data['email']

        #         if not user.is_email_verified(potential_email):
        #             raise serializers.ValidationError(
        #                 "Issuer email must be one of your verified addresses. Add this email to your profile and try again.")

        staff = validated_data.pop('staff_items', [])
        new_issuer = super(IssuerSerializerV2, self).create(validated_data)

        # update staff after issuer is created
        new_issuer.staff_items = staff

        # set badgrapp
        new_issuer.badgrapp = BadgrApp.objects.get_current(
            self.context.get('request', None))

        return new_issuer
示例#22
0
class AssociateRetrieveSerializer(serializers.Serializer):
    # ------ MEMBER ------ #

    slug = serializers.SlugField(
        source="user.slug",
        read_only=True,
    )
    type_of = serializers.IntegerField(
        source="user.member.type_of",
        read_only=True,
    )
    type_of_label = serializers.CharField(
        source="user.member.get_pretty_type_of",
        read_only=True,
    )
    avatar_url = serializers.SerializerMethodField()
    state = serializers.CharField(
        source="user.member.state",
        read_only=True,
    )

    # ------ MEMBER CONTACT ------ #

    is_ok_to_email = serializers.IntegerField(
        source="user.member.contact.is_ok_to_email",
        read_only=True,
    )
    is_ok_to_text = serializers.IntegerField(
        source="user.member.contact.is_ok_to_text",
        read_only=True,
    )
    organization_name = serializers.CharField(
        source="user.member.contact.organization_name",
        read_only=True,
        allow_blank=True,
    )
    organization_type_of = serializers.IntegerField(
        source="user.member.contact.organization_type_of",
        read_only=True,
    )
    first_name = serializers.CharField(
        source="user.member.contact.first_name",
        read_only=True,
    )
    last_name = serializers.CharField(
        source="user.member.contact.last_name",
        read_only=True,
    )
    full_name = serializers.SerializerMethodField()
    email = serializers.EmailField(
        source="user.member.contact.email",
        read_only=True,
    )
    primary_phone_e164 = E164PhoneNumberField(
        source="user.member.contact.primary_phone",
        read_only=True,
    )
    primary_phone_national = NationalPhoneNumberField(
        source="user.member.contact.primary_phone",
        read_only=True,
    )
    secondary_phone_e164 = E164PhoneNumberField(
        source="user.member.contact.secondary_phone",
        read_only=True,
    )
    secondary_phone_national = NationalPhoneNumberField(
        source="user.member.contact.secondary_phone",
        read_only=True,
    )

    # ------ MEMBER ADDRESS ------ #

    country = serializers.CharField(
        source="user.member.address.country",
        read_only=True,
    )
    province = serializers.CharField(
        source="user.member.address.province",
        read_only=True,
    )
    city = serializers.CharField(
        source="user.member.address.city",
        read_only=True,
    )
    street_number = serializers.CharField(
        source="user.member.address.street_number",
        read_only=True,
    )
    street_name = serializers.CharField(
        source="user.member.address.street_name",
        read_only=True,
    )
    apartment_unit = serializers.CharField(
        source="user.member.address.apartment_unit",
        read_only=True,
    )
    street_type = serializers.IntegerField(
        source="user.member.address.street_type",
        read_only=True,
    )
    street_type_other = serializers.CharField(
        source="user.member.address.street_type_other",
        read_only=True,
    )
    street_direction = serializers.IntegerField(
        source="user.member.address.street_direction",
        read_only=True,
    )
    postal_code = serializers.CharField(
        source="user.member.address.postal_code",
        read_only=True,
    )
    address = serializers.CharField(
        source="user.member.address.street_address",
        read_only=True,
    )
    google_maps_url = serializers.URLField(
        source="user.member.address.google_maps_url",
        read_only=True,
    )
    position = serializers.SerializerMethodField()

    # ------ MEMBER WATCH ------ #

    #TODO: IMPLEMENT FIELDS.

    # ------ MEMBER METRICS ------ #

    tags = TagListCreateSerializer(
        source="user.member.metric.tags",
        many=True,
        read_only=True,
    )
    how_did_you_hear = serializers.PrimaryKeyRelatedField(
        source="user.member.metric.how_did_you_hear",
        many=False,
        read_only=True,
        allow_null=False,
    )
    how_did_you_hear_other = serializers.CharField(
        source="user.member.metric.how_did_you_hear_other",
        allow_null=True,
        allow_blank=True,
        read_only=True,
    )
    how_did_you_hear_label = serializers.CharField(
        source="user.member.metric.how_did_you_hear.text",
        read_only=True,
        allow_blank=True,
        allow_null=True,
    )
    expectation = serializers.PrimaryKeyRelatedField(
        source="user.member.metric.expectation",
        many=False,
        read_only=True,
        allow_null=False,
    )
    expectation_other = serializers.CharField(
        source="user.member.metric.expectation_other",
        allow_null=True,
        allow_blank=True,
        read_only=True,
    )
    expectation_label = serializers.CharField(
        source="user.member.metric.expectation.text",
        read_only=True,
        allow_null=True,
        allow_blank=True,
    )
    meaning = serializers.PrimaryKeyRelatedField(
        source="user.member.metric.meaning",
        many=False,
        read_only=True,
        allow_null=False,
    )
    meaning_other = serializers.CharField(
        source="user.member.metric.meaning_other",
        allow_null=True,
        allow_blank=True,
        read_only=True,
    )
    meaning_label = serializers.CharField(
        source="user.member.metric.meaning.text",
        read_only=True,
        allow_null=True,
        allow_blank=True,
    )
    gender = serializers.IntegerField(
        source="user.member.metric.gender",
        read_only=True,
    )
    gender_label = serializers.CharField(
        source="user.member.metric.get_pretty_gender",
        read_only=True,
    )
    willing_to_volunteer = serializers.IntegerField(
        source="user.member.metric.willing_to_volunteer",
        read_only=True,
    )
    willing_to_volunteer_label = serializers.CharField(
        source="user.member.metric.get_pretty_willing_to_volunteer",
        read_only=True,
    )
    another_household_member_registered = serializers.BooleanField(
        source="user.member.metric.another_household_member_registered",
        read_only=True,
    )
    year_of_birth = serializers.IntegerField(
        source="user.member.metric.year_of_birth",
        read_only=True,
    )
    total_household_count = serializers.IntegerField(
        source="user.member.metric.total_household_count",
        read_only=True,
    )
    over_18_years_household_count = serializers.IntegerField(
        source="user.member.metric.over_18_years_household_count",
        read_only=True,
    )
    organization_employee_count = serializers.IntegerField(
        source="user.member.metric.organization_employee_count",
        read_only=True,
    )
    organization_founding_year = serializers.IntegerField(
        source="user.member.metric.organization_founding_year",
        read_only=True,
    )
    governing = serializers.SerializerMethodField()

    # ------ AUDITING ------ #

    created_by = serializers.CharField(
        source="created_by.get_full_name",
        allow_null=True,
        read_only=True,
    )
    last_modified_by = serializers.CharField(
        source="last_modified_by.get_full_name",
        allow_null=True,
        read_only=True,
    )

    # ------ FUNCTIONS ------ #

    def get_full_name(self, obj):
        try:
            return obj.user.member.contact.first_name + " " + obj.user.member.contact.last_name
        except Exception as e:
            print(e)
            return None

    def get_avatar_url(self, obj):
        try:
            return obj.user.member.avatar_image.image_file.url
        except Exception as e:
            return

    def get_governing(self, obj):
        try:
            s = GoverningDistrictRetrieveSerializer(obj.governing.all(),
                                                    many=True,
                                                    context=self.context)
            return s.data
        except Exception as e:
            # print("get_governing |", e)
            return None

    def get_position(self, obj):
        return get_arr_from_point(obj.user.member.address.position)
class DistrictUpdateSerializer(serializers.Serializer):
    slug = serializers.SlugField(write_only=True, )
    type_of = serializers.IntegerField(
        write_only=True,
        required=True,
    )
    name = serializers.CharField(
        write_only=True,
        required=True,
    )
    description = serializers.CharField(
        write_only=True,
        required=False,
    )
    counselor_name = serializers.CharField(
        write_only=True,
        required=False,
    )
    counselor_email = serializers.EmailField(
        write_only=True,
        required=False,
    )
    counselor_phone = serializers.CharField(
        write_only=True,
        required=False,
    )
    website_url = serializers.URLField(
        write_only=True,
        required=False,
        allow_blank=True,
        allow_null=True,
    )
    is_archived = serializers.BooleanField(
        write_only=True,
        required=False,
    )
    facebook_url = serializers.URLField(
        required=False,
        allow_blank=True,
        allow_null=True,
    )

    # REACT-DJANGO UPLOAD | STEP 1 OF 4: We define two string fields required (write-only)
    # for accepting our file uploads.
    upload_content = serializers.CharField(
        write_only=True,
        allow_null=True,
        allow_blank=True,
        required=False,
    )
    upload_filename = serializers.CharField(
        write_only=True,
        allow_null=True,
        allow_blank=True,
        required=False,
    )

    def update(self, instance, validated_data):
        request = self.context.get("request")
        instance.type_of = validated_data.get('type_of')
        instance.description = validated_data.get('description')
        instance.name = validated_data.get('name')
        instance.counselor_name = validated_data.get('counselor_name', None)
        instance.counselor_email = validated_data.get('counselor_email', None)
        instance.counselor_phone = validated_data.get('counselor_phone', None)
        instance.website_url = validated_data.get('website_url', None)
        instance.facebook_url = validated_data.get('facebook_url', None)
        instance.created_by = request.user
        instance.created_from = request.client_ip
        instance.created_from_is_public = request.client_ip_is_routable
        instance.last_modified_by = request.user
        instance.last_modified_from = request.client_ip
        instance.last_modified_from_is_public = request.client_ip_is_routable
        instance.save()
        logger.info("New district was been updated.")

        try:
            # Extract our upload file data
            content = validated_data.get('upload_content', None)
            filename = validated_data.get('upload_filename', None)

            if content and filename:
                if settings.DEBUG:
                    filename = "QA_" + filename  # NOTE: Attach `QA_` prefix if server running in QA mode.
                content_file = get_content_file_from_base64_string(
                    content, filename
                )  # REACT-DJANGO UPLOAD | STEP 3 OF 4: Convert to `ContentFile` type.

                # Create our file.
                private_file = PrivateImageUpload.objects.create(
                    is_archived=False,
                    user=request.user,
                    image_file=
                    content_file,  # REACT-DJANGO UPLOAD | STEP 4 OF 4: When you attack a `ContentImage`, Django handles all file uploading.
                    created_by=request.user,
                    created_from=request.client_ip,
                    created_from_is_public=request.client_ip_is_routable,
                    last_modified_by=request.user,
                    last_modified_from=request.client_ip,
                    last_modified_from_is_public=request.client_ip_is_routable,
                )
                logger.info("Private file was been created.")
                instance.logo_image = private_file
                instance.save()
        except Exception as e:
            print(e)
            private_file = None

        # raise serializers.ValidationError({ # Uncomment when not using this code but do not delete!
        #     "error": "Terminating for debugging purposes only."
        # })

        return instance
示例#24
0
class UploadBlobSerializer(NoModelSerializer):
    """
    Upload a picture or other POD content
    """
    location = serializers.URLField(help_text=_("URL to uploaded content"))
示例#25
0
class CodebaseReleaseSerializer(serializers.ModelSerializer):
    absolute_url = serializers.URLField(
        source='get_absolute_url',
        read_only=True,
        help_text=_('URL to the detail page of the codebase'))
    citation_text = serializers.ReadOnlyField()
    codebase = CodebaseSerializer(read_only=True)
    release_contributors = ReleaseContributorSerializer(
        read_only=True, source='index_ordered_release_contributors', many=True)
    date_created = serializers.DateTimeField(format=YMD_DATETIME_FORMAT,
                                             read_only=True)
    first_published_at = serializers.DateTimeField(
        format=DATE_PUBLISHED_FORMAT, read_only=True)
    last_published_on = serializers.DateTimeField(format=DATE_PUBLISHED_FORMAT,
                                                  read_only=True)
    output_data_url = serializers.URLField(required=False)
    license = LicenseSerializer()
    live = serializers.ReadOnlyField()
    os_display = serializers.ReadOnlyField(source='get_os_display')
    platforms = TagSerializer(many=True, source='platform_tags')
    programming_languages = TagSerializer(many=True)
    submitter = LinkedUserSerializer(read_only=True, label='Submitter')
    version_number = serializers.ReadOnlyField()
    release_notes = MarkdownField(max_length=2048)
    urls = serializers.SerializerMethodField()
    review_status = serializers.SerializerMethodField()

    def get_urls(self, instance):
        request_peer_review_url = instance.get_request_peer_review_url()
        review = instance.get_review()
        review_url = review.get_absolute_url() if review else None
        notify_reviewers_of_changes_url = instance.get_notify_reviewers_of_changes_url(
        ) if review else None
        return {
            'request_peer_review': request_peer_review_url,
            'review': review_url,
            'notify_reviewers_of_changes': notify_reviewers_of_changes_url
        }

    def get_review_status(self, instance):
        return instance.review.status if instance.get_review() else None

    class Meta:
        model = CodebaseRelease
        fields = (
            'absolute_url',
            'citation_text',
            'release_contributors',
            'date_created',
            'dependencies',
            'release_notes',
            'documentation',
            'doi',
            'download_count',
            'embargo_end_date',
            'first_published_at',
            'last_modified',
            'last_published_on',
            'license',
            'live',
            'os',
            'os_display',
            'peer_reviewed',
            'platforms',
            'programming_languages',
            'submitted_package',
            'submitter',
            'codebase',
            'review_status',
            'output_data_url',
            'version_number',
            'id',
            'share_url',
            'urls',
        )
示例#26
0
class UserMainSerializer(rest_serializers.ModelSerializer):
    cost_sum = rest_serializers.IntegerField(read_only=True)
    avatar_main = rest_serializers.URLField(source='avatar.main.url',
                                            read_only=True)
    avatar_small = rest_serializers.URLField(source='avatar.small.url',
                                             read_only=True)
    old_password = rest_serializers.CharField(write_only=True,
                                              required=False,
                                              allow_blank=True)
    password = rest_serializers.CharField(write_only=True,
                                          required=False,
                                          allow_blank=True)
    personal_info = UserPersonalInfoSerializer(required=False)
    can_create_tasks = rest_serializers.BooleanField(read_only=True)
    can_create_contests = rest_serializers.BooleanField(read_only=True)
    is_admin = rest_serializers.BooleanField(read_only=True)

    class Meta:
        model = api.models.User
        fields = (
            'avatar_main',
            'avatar_small',
            'can_create_contests',
            'can_create_tasks',
            'cost_sum',
            'email',
            'is_admin',
            'hide_personal_info',
            'id',
            'max_rating',
            'old_password',
            'password',
            'personal_info',
            'rating',
            'username',
        )

        extra_kwargs = {
            'password': {
                'write_only': True,
            },
            'email': {
                'read_only': True,
            },
            'rating': {
                'read_only': True,
            },
            'max_rating': {
                'read_only': True,
            },
            'username': {
                'read_only': True,
            },
        }

    def validate(self, data):
        password = data.pop('password', None)
        old_password = data.pop('old_password', None)

        user = self.instance

        if not password:
            return data

        if not old_password:
            raise rest_serializers.ValidationError({
                'old_password':
                '******'
            })

        if not user.check_password(raw_password=old_password):
            raise rest_serializers.ValidationError(
                {'old_password': '******'})

        errors = dict()
        try:
            validate_password(password=password, user=user)
        except django_core_exceptions.ValidationError as e:
            errors['password'] = list(e.messages)

        if errors:
            raise rest_serializers.ValidationError(errors)

        data['password'] = password
        return data

    def update(self, instance, validated_data):
        password = validated_data.pop('password', None)

        personal_info = validated_data.pop('personal_info', None)
        if personal_info:
            validated_data.update(**personal_info)

        if password:
            instance.set_password(password)

        return super(UserMainSerializer, self).update(instance, validated_data)
示例#27
0
class VersionURLsSerializer(serializers.Serializer):
    documentation = serializers.SerializerMethodField()
    vcs = serializers.URLField(source='vcs_url')

    def get_documentation(self, obj):
        return obj.project.get_docs_url(version_slug=obj.slug, )
示例#28
0
class BadgeInstanceSerializerV1(OriginalJsonSerializerMixin,
                                serializers.Serializer):
    created_at = DateTimeWithUtcZAtEndField(read_only=True,
                                            default_timezone=pytz.utc)
    created_by = BadgeUserIdentifierFieldV1(read_only=True)
    slug = serializers.CharField(max_length=255,
                                 read_only=True,
                                 source='entity_id')
    image = serializers.FileField(
        read_only=True)  # use_url=True, might be necessary
    email = serializers.EmailField(max_length=1024,
                                   required=False,
                                   write_only=True)
    recipient_identifier = serializers.CharField(max_length=1024,
                                                 required=False)
    recipient_type = serializers.CharField(default=RECIPIENT_TYPE_EMAIL)
    allow_uppercase = serializers.BooleanField(default=False,
                                               required=False,
                                               write_only=True)
    evidence = serializers.URLField(write_only=True,
                                    required=False,
                                    allow_blank=True,
                                    max_length=1024)
    narrative = MarkdownCharField(required=False,
                                  allow_blank=True,
                                  allow_null=True)
    evidence_items = EvidenceItemSerializer(many=True, required=False)

    revoked = HumanReadableBooleanField(read_only=True)
    revocation_reason = serializers.CharField(read_only=True)

    expires = DateTimeWithUtcZAtEndField(source='expires_at',
                                         required=False,
                                         allow_null=True,
                                         default_timezone=pytz.utc)

    create_notification = HumanReadableBooleanField(write_only=True,
                                                    required=False,
                                                    default=False)
    allow_duplicate_awards = serializers.BooleanField(write_only=True,
                                                      required=False,
                                                      default=True)
    hashed = serializers.NullBooleanField(default=None, required=False)

    extensions = serializers.DictField(source='extension_items',
                                       required=False,
                                       validators=[BadgeExtensionValidator()])

    class Meta:
        apispec_definition = ('Assertion', {})

    def validate(self, data):
        recipient_type = data.get('recipient_type')
        if data.get('recipient_identifier') and data.get('email') is None:
            if recipient_type == RECIPIENT_TYPE_EMAIL:
                recipient_validator = EmailValidator()
            elif recipient_type in (RECIPIENT_TYPE_URL, RECIPIENT_TYPE_ID):
                recipient_validator = URLValidator()
            else:
                recipient_validator = TelephoneValidator()

            try:
                recipient_validator(data['recipient_identifier'])
            except DjangoValidationError as e:
                raise serializers.ValidationError(e.message)

        elif data.get('email') and data.get('recipient_identifier') is None:
            data['recipient_identifier'] = data.get('email')

        allow_duplicate_awards = data.pop('allow_duplicate_awards')
        if allow_duplicate_awards is False and self.context.get(
                'badgeclass') is not None:
            previous_awards = BadgeInstance.objects.filter(
                recipient_identifier=data['recipient_identifier'],
                badgeclass=self.context['badgeclass']).filter(
                    Q(expires_at__isnull=True)
                    | Q(expires_at__lt=timezone.now()))
            if previous_awards.exists():
                raise serializers.ValidationError(
                    "A previous award of this badge already exists for this recipient."
                )

        hashed = data.get('hashed', None)
        if hashed is None:
            if recipient_type in (RECIPIENT_TYPE_URL, RECIPIENT_TYPE_ID):
                data['hashed'] = False
            else:
                data['hashed'] = True

        return data

    def validate_narrative(self, data):
        if data is None or data == "":
            return None
        else:
            return data

    def to_representation(self, instance):
        representation = super(BadgeInstanceSerializerV1,
                               self).to_representation(instance)
        representation['json'] = instance.get_json(obi_version="1_1",
                                                   use_canonical_id=True)
        if self.context.get('include_issuer', False):
            representation['issuer'] = IssuerSerializerV1(
                instance.cached_badgeclass.cached_issuer).data
        else:
            representation['issuer'] = OriginSetting.HTTP + reverse(
                'issuer_json',
                kwargs={'entity_id': instance.cached_issuer.entity_id})
        if self.context.get('include_badge_class', False):
            representation['badge_class'] = BadgeClassSerializerV1(
                instance.cached_badgeclass, context=self.context).data
        else:
            representation['badge_class'] = OriginSetting.HTTP + reverse(
                'badgeclass_json',
                kwargs={'entity_id': instance.cached_badgeclass.entity_id})

        representation['public_url'] = OriginSetting.HTTP + reverse(
            'badgeinstance_json', kwargs={'entity_id': instance.entity_id})

        return representation

    def create(self, validated_data):
        """
        Requires self.context to include request (with authenticated request.user)
        and badgeclass: issuer.models.BadgeClass.
        """
        evidence_items = []

        # ob1 evidence url
        evidence_url = validated_data.get('evidence')
        if evidence_url:
            evidence_items.append({'evidence_url': evidence_url})

        # ob2 evidence items
        submitted_items = validated_data.get('evidence_items')
        if submitted_items:
            evidence_items.extend(submitted_items)
        try:
            return self.context.get('badgeclass').issue(
                recipient_id=validated_data.get('recipient_identifier'),
                narrative=validated_data.get('narrative'),
                evidence=evidence_items,
                notify=validated_data.get('create_notification'),
                created_by=self.context.get('request').user,
                allow_uppercase=validated_data.get('allow_uppercase'),
                recipient_type=validated_data.get('recipient_type',
                                                  RECIPIENT_TYPE_EMAIL),
                badgr_app=BadgrApp.objects.get_current(
                    self.context.get('request')),
                expires_at=validated_data.get('expires_at', None),
                extensions=validated_data.get('extension_items', None))
        except DjangoValidationError as e:
            raise serializers.ValidationError(e.message)

    def update(self, instance, validated_data):
        updateable_fields = [
            'evidence_items', 'expires_at', 'extension_items', 'hashed',
            'narrative', 'recipient_identifier', 'recipient_type'
        ]

        for field_name in updateable_fields:
            if field_name in validated_data:
                setattr(instance, field_name, validated_data.get(field_name))
        instance.rebake(save=False)
        instance.save()

        return instance
示例#29
0
class PasswordResetSerializer(UsernameOrEmailSerializer):
    """Serializer to request a password reset e-mail."""

    redirect_uri = serializers.URLField(required=False)
示例#30
0
class ScreenOneSerializer(serializers.Serializer):
    Home = serializers.ReadOnlyField()
    Video = serializers.URLField(read_only=True)
    appointment = serializers.URLField(read_only=True)