コード例 #1
0
ファイル: serializers.py プロジェクト: ubiquitypress/osf.io
class NodeProviderSerializer(JSONAPISerializer):

    id = ser.SerializerMethodField(read_only=True)
    kind = ser.CharField(read_only=True)
    name = ser.CharField(read_only=True)
    path = ser.CharField(read_only=True)
    node = ser.CharField(source='node_id', read_only=True)
    provider = ser.CharField(read_only=True)
    files = NodeFileHyperLinkField(
        related_view='nodes:node-files',
        related_view_kwargs={'node_id': '<node_id>', 'path': '<path>', 'provider': '<provider>'},
        kind='folder',
        never_embed=True
    )
    links = LinksField({
        'upload': WaterbutlerLink(),
        'new_folder': WaterbutlerLink(kind='folder')
    })

    class Meta:
        type_ = 'files'

    @staticmethod
    def get_id(obj):
        return '{}:{}'.format(obj.node._id, obj.provider)
コード例 #2
0
ファイル: serializers.py プロジェクト: jwalz/osf.io
class DraftNodeStorageProviderSerializer(NodeStorageProviderSerializer):
    files = NodeFileHyperLinkField(
        related_view='draft_nodes:node-files',
        related_view_kwargs={'node_id': '<node._id>', 'path': '<path>', 'provider': '<provider>'},
        kind='folder',
        never_embed=True,
    )
コード例 #3
0
class RegistrationStorageProviderSerializer(NodeStorageProviderSerializer):
    """
    Overrides NodeStorageProviderSerializer to lead to correct registration file links
    """
    files = NodeFileHyperLinkField(
        related_view='registrations:registration-files',
        related_view_kwargs={'node_id': '<target._id>', 'path': '<path>', 'provider': '<provider>'},
        kind='folder',
        never_embed=True,
    )
コード例 #4
0
ファイル: serializers.py プロジェクト: fugokidi/osf.io
class PreprintStorageProviderSerializer(NodeStorageProviderSerializer):
    node = HideIfPreprint(ser.CharField(source='node_id', read_only=True))
    preprint = ser.CharField(source='node_id', read_only=True)

    files = NodeFileHyperLinkField(
        related_view='preprints:preprint-files',
        related_view_kwargs={'preprint_id': '<node._id>'},
        kind='folder',
        never_embed=True,
    )

    links = LinksField({
        'upload': WaterbutlerLink(),
    })
コード例 #5
0
class NodeProviderSerializer(JSONAPISerializer):
    id = ser.SerializerMethodField(read_only=True)
    kind = ser.CharField(read_only=True)
    name = ser.CharField(read_only=True)
    path = ser.CharField(read_only=True)
    node = ser.CharField(source='node_id', read_only=True)
    provider = ser.CharField(read_only=True)
    files = NodeFileHyperLinkField(related_view='nodes:node-files',
                                   related_view_kwargs={
                                       'node_id': '<node._id>',
                                       'path': '<path>',
                                       'provider': '<provider>'
                                   },
                                   kind='folder',
                                   never_embed=True)
    links = LinksField({
        'upload': WaterbutlerLink(),
        'new_folder': WaterbutlerLink(kind='folder'),
        'storage_addons': 'get_storage_addons_url'
    })

    class Meta:
        type_ = 'files'

    @staticmethod
    def get_id(obj):
        return '{}:{}'.format(obj.node._id, obj.provider)

    def get_absolute_url(self, obj):
        return absolute_reverse(
            'nodes:node-provider-detail',
            kwargs={
                'node_id':
                obj.node._id,
                'provider':
                obj.provider,
                'version':
                self.context['request'].parser_context['kwargs']['version']
            })

    def get_storage_addons_url(self, obj):
        return absolute_reverse(
            'addons:addon-list',
            kwargs={
                'version':
                self.context['request'].parser_context['kwargs']['version']
            },
            query_kwargs={'filter[categories]': 'storage'})
コード例 #6
0
ファイル: serializers.py プロジェクト: fredtoh/osf.io
class RegistrationFileSerializer(FileSerializer):

    files = NodeFileHyperLinkField(
        related_view='registrations:registration-files',
        related_view_kwargs={
            'node_id': '<node_id>',
            'path': '<path>',
            'provider': '<provider>'
        },
        kind='folder')

    comments = FileCommentRelationshipField(
        related_view='registrations:registration-comments',
        related_view_kwargs={'node_id': '<node._id>'},
        related_meta={'unread': 'get_unread_comments_count'},
        filter={'target': 'get_file_guid'})
コード例 #7
0
class RegistrationFileSerializer(OsfStorageFileSerializer):

    files = NodeFileHyperLinkField(
        related_view='registrations:registration-files',
        related_view_kwargs={'node_id': '<node._id>', 'path': '<path>', 'provider': '<provider>'},
        kind='folder'
    )

    comments = FileCommentRelationshipField(related_view='registrations:registration-comments',
                                            related_view_kwargs={'node_id': '<node._id>'},
                                            related_meta={'unread': 'get_unread_comments_count'},
                                            filter={'target': 'get_file_guid'}
                                            )

    node = RelationshipField(related_view='registrations:registration-detail',
                                     related_view_kwargs={'node_id': '<node._id>'},
                                     help_text='The registration that this file belongs to'
                             )
コード例 #8
0
class BaseFileSerializer(JSONAPISerializer):
    filterable_fields = frozenset([
        'id',
        'name',
        'kind',
        'path',
        'materialized_path',
        'size',
        'provider',
        'last_touched',
        'tags',
    ])
    id = IDField(source='_id', read_only=True)
    type = TypeField()
    guid = ser.SerializerMethodField(
        read_only=True,
        method_name='get_file_guid',
        help_text='OSF GUID for this file (if one has been assigned)',
    )
    checkout = CheckoutField()
    name = ser.CharField(
        read_only=True,
        help_text='Display name used in the general user interface')
    kind = ser.CharField(read_only=True, help_text='Either folder or file')
    path = ser.CharField(
        read_only=True,
        help_text='The unique path used to reference this object')
    size = ser.SerializerMethodField(
        read_only=True, help_text='The size of this file at this version')
    provider = ser.CharField(
        read_only=True,
        help_text='The Add-on service this file originates from')
    materialized_path = ser.CharField(
        read_only=True,
        help_text=
        'The Unix-style path of this object relative to the provider root',
    )
    last_touched = VersionedDateTimeField(
        read_only=True,
        help_text=
        'The last time this file had information fetched about it via the OSF')
    date_modified = ser.SerializerMethodField(
        read_only=True, help_text='Timestamp when the file was last modified')
    date_created = ser.SerializerMethodField(
        read_only=True, help_text='Timestamp when the file was created')
    extra = ser.SerializerMethodField(
        read_only=True, help_text='Additional metadata about this file')
    tags = JSONAPIListField(child=FileTagField(), required=False)
    current_user_can_comment = ser.SerializerMethodField(
        help_text='Whether the current user is allowed to post comments')
    current_version = ser.IntegerField(help_text='Latest file version',
                                       read_only=True,
                                       source='current_version_number')
    delete_allowed = ser.BooleanField(read_only=True, required=False)

    parent_folder = RelationshipField(
        related_view='files:file-detail',
        related_view_kwargs={'file_id': '<parent._id>'},
        help_text='The folder in which this file exists',
    )
    files = NodeFileHyperLinkField(
        related_view=lambda node: disambiguate_files_related_view(node),
        view_lambda_argument='target',
        related_view_kwargs=lambda filenode:
        disambiguate_files_related_view_kwargs(filenode),
        kind='folder',
    )
    versions = NodeFileHyperLinkField(
        related_view='files:file-versions',
        related_view_kwargs={'file_id': '<_id>'},
        kind='file',
    )
    comments = HideIfPreprint(
        FileRelationshipField(
            related_view='nodes:node-comments',
            related_view_kwargs={'node_id': '<target._id>'},
            related_meta={'unread': 'get_unread_comments_count'},
            filter={'target': 'get_file_guid'},
        ))
    metadata_records = FileRelationshipField(
        related_view='files:metadata-records',
        related_view_kwargs={'file_id': '<_id>'},
    )

    links = LinksField({
        'info':
        Link('files:file-detail', kwargs={'file_id': '<_id>'}),
        'move':
        WaterbutlerLink(),
        'upload':
        WaterbutlerLink(),
        'delete':
        WaterbutlerLink(),
        'download':
        'get_download_link',
        'render':
        'get_render_link',
        'html':
        'absolute_url',
        'new_folder':
        WaterbutlerLink(must_be_folder=True, kind='folder'),
    })

    def absolute_url(self, obj):
        if obj.is_file:
            return furl.furl(settings.DOMAIN).set(
                path=(obj.target._id, 'files', obj.provider,
                      obj.path.lstrip('/')), ).url

    def get_download_link(self, obj):
        if obj.is_file:
            return get_file_download_link(
                obj,
                view_only=self.context['request'].query_params.get(
                    'view_only'))

    def get_render_link(self, obj):
        if obj.is_file:
            mfr_url = get_mfr_url(obj.target, obj.provider)
            download_url = self.get_download_link(obj)
            return get_file_render_link(mfr_url, download_url)

    class Meta:
        type_ = 'files'

    def get_size(self, obj):
        if obj.versions.exists():
            self.size = obj.versions.first().size
            return self.size
        return None

    def get_date_modified(self, obj):
        mod_dt = None
        if obj.provider == 'osfstorage' and obj.versions.exists():
            # Each time an osfstorage file is added or uploaded, a new version object is created with its
            # date_created equal to the time of the update.  The external_modified is the modified date
            # from the backend the file is stored on.  This field refers to the modified date on osfstorage,
            # so prefer to use the created of the latest version.
            mod_dt = obj.versions.first().created
        elif obj.provider != 'osfstorage' and obj.history:
            mod_dt = obj.history[-1].get('modified', None)

        if self.context['request'].version >= '2.2' and obj.is_file and mod_dt:
            return datetime.strftime(mod_dt, '%Y-%m-%dT%H:%M:%S.%fZ')

        return mod_dt and mod_dt.replace(tzinfo=pytz.utc)

    def get_date_created(self, obj):
        creat_dt = None
        if obj.provider == 'osfstorage' and obj.versions.exists():
            creat_dt = obj.versions.last().created
        elif obj.provider != 'osfstorage' and obj.history:
            # Non-osfstorage files don't store a created date, so instead get the modified date of the
            # earliest entry in the file history.
            creat_dt = obj.history[0].get('modified', None)

        if self.context[
                'request'].version >= '2.2' and obj.is_file and creat_dt:
            return datetime.strftime(creat_dt, '%Y-%m-%dT%H:%M:%S.%fZ')

        return creat_dt and creat_dt.replace(tzinfo=pytz.utc)

    def get_extra(self, obj):
        metadata = {}
        if obj.provider == 'osfstorage' and obj.versions.exists():
            metadata = obj.versions.first().metadata
        elif obj.provider != 'osfstorage' and obj.history:
            metadata = obj.history[-1].get('extra', {})

        extras = {}
        extras['hashes'] = {  # mimic waterbutler response
            'md5': metadata.get('md5', None),
            'sha256': metadata.get('sha256', None),
        }
        if obj.provider == 'osfstorage' and obj.is_file:
            extras['downloads'] = obj.get_download_count()
        return extras

    def get_current_user_can_comment(self, obj):
        user = self.context['request'].user
        auth = Auth(user if not user.is_anonymous else None)
        if isinstance(obj.target, AbstractNode):
            return obj.target.can_comment(auth)
        return False

    def get_unread_comments_count(self, obj):
        user = self.context['request'].user
        if user.is_anonymous:
            return 0
        return Comment.find_n_unread(user=user,
                                     node=obj.target,
                                     page='files',
                                     root_id=obj.get_guid()._id)

    def user_id(self, obj):
        # NOTE: obj is the user here, the meta field for
        # Hyperlinks is weird
        if obj:
            return obj._id
        return None

    def update(self, instance, validated_data):
        assert isinstance(instance,
                          BaseFileNode), 'Instance must be a BaseFileNode'
        if instance.provider != 'osfstorage' and 'tags' in validated_data:
            raise Conflict(
                'File service provider {} does not support tags on the OSF.'.
                format(instance.provider))
        auth = get_user_auth(self.context['request'])
        old_tags = set(instance.tags.values_list('name', flat=True))
        if 'tags' in validated_data:
            current_tags = set(validated_data.pop('tags', []))
        else:
            current_tags = set(old_tags)

        for new_tag in (current_tags - old_tags):
            instance.add_tag(new_tag, auth=auth)
        for deleted_tag in (old_tags - current_tags):
            instance.remove_tag(deleted_tag, auth=auth)

        for attr, value in validated_data.items():
            if attr == 'checkout':
                user = self.context['request'].user
                instance.check_in_or_out(user, value)
            else:
                setattr(instance, attr, value)
        instance.save()
        return instance

    def is_valid(self, **kwargs):
        return super(BaseFileSerializer, self).is_valid(clean_html=False,
                                                        **kwargs)

    def get_file_guid(self, obj):
        if obj:
            guid = obj.get_guid()
            if guid:
                return guid._id
        return None

    def get_absolute_url(self, obj):
        return api_v2_url('files/{}/'.format(obj._id))
コード例 #9
0
class FileSerializer(JSONAPISerializer):
    filterable_fields = frozenset([
        'id',
        'name',
        'node',
        'kind',
        'path',
        'materialized_path',
        'size',
        'provider',
        'last_touched',
        'tags',
    ])
    id = IDField(source='_id', read_only=True)
    type = TypeField()
    checkout = CheckoutField()
    name = ser.CharField(
        read_only=True,
        help_text='Display name used in the general user interface')
    kind = ser.CharField(read_only=True, help_text='Either folder or file')
    path = ser.CharField(
        read_only=True,
        help_text='The unique path used to reference this object')
    size = ser.SerializerMethodField(
        read_only=True, help_text='The size of this file at this version')
    provider = ser.CharField(
        read_only=True,
        help_text='The Add-on service this file originates from')
    materialized_path = ser.CharField(
        read_only=True,
        help_text=
        'The Unix-style path of this object relative to the provider root')
    last_touched = ser.DateTimeField(
        read_only=True,
        help_text=
        'The last time this file had information fetched about it via the OSF')
    date_modified = ser.SerializerMethodField(
        read_only=True, help_text='Timestamp when the file was last modified')
    date_created = ser.SerializerMethodField(
        read_only=True, help_text='Timestamp when the file was created')
    extra = ser.SerializerMethodField(
        read_only=True, help_text='Additional metadata about this file')
    tags = JSONAPIListField(child=FileTagField(), required=False)

    files = NodeFileHyperLinkField(related_view='nodes:node-files',
                                   related_view_kwargs={
                                       'node_id': '<node_id>',
                                       'path': '<path>',
                                       'provider': '<provider>'
                                   },
                                   kind='folder')
    versions = NodeFileHyperLinkField(related_view='files:file-versions',
                                      related_view_kwargs={'file_id': '<_id>'},
                                      kind='file')
    comments = FileCommentRelationshipField(
        related_view='nodes:node-comments',
        related_view_kwargs={'node_id': '<node._id>'},
        related_meta={'unread': 'get_unread_comments_count'},
        filter={'target': 'get_file_guid'})
    links = LinksField({
        'info':
        Link('files:file-detail', kwargs={'file_id': '<_id>'}),
        'move':
        WaterbutlerLink(),
        'upload':
        WaterbutlerLink(),
        'delete':
        WaterbutlerLink(),
        'download':
        WaterbutlerLink(must_be_file=True),
        'new_folder':
        WaterbutlerLink(must_be_folder=True, kind='folder'),
    })

    class Meta:
        type_ = 'files'

    def get_size(self, obj):
        if obj.versions:
            return obj.versions[-1].size
        return None

    def get_date_modified(self, obj):
        mod_dt = None
        if obj.provider == 'osfstorage' and obj.versions:
            # Each time an osfstorage file is added or uploaded, a new version object is created with its
            # date_created equal to the time of the update.  The date_modified is the modified date
            # from the backend the file is stored on.  This field refers to the modified date on osfstorage,
            # so prefer to use the date_created of the latest version.
            mod_dt = obj.versions[-1].date_created
        elif obj.provider != 'osfstorage' and obj.history:
            mod_dt = obj.history[-1].get('modified', None)

        return mod_dt and mod_dt.replace(tzinfo=pytz.utc)

    def get_date_created(self, obj):
        creat_dt = None
        if obj.provider == 'osfstorage' and obj.versions:
            creat_dt = obj.versions[0].date_created
        elif obj.provider != 'osfstorage' and obj.history:
            # Non-osfstorage files don't store a created date, so instead get the modified date of the
            # earliest entry in the file history.
            creat_dt = obj.history[0].get('modified', None)

        return creat_dt and creat_dt.replace(tzinfo=pytz.utc)

    def get_extra(self, obj):
        metadata = {}
        if obj.provider == 'osfstorage' and obj.versions:
            metadata = obj.versions[-1].metadata
        elif obj.provider != 'osfstorage' and obj.history:
            metadata = obj.history[-1].get('extra', {})

        extras = {}
        extras['hashes'] = {  # mimic waterbutler response
            'md5': metadata.get('md5', None),
            'sha256': metadata.get('sha256', None),
        }
        return extras

    def get_unread_comments_count(self, obj):
        user = self.context['request'].user
        if user.is_anonymous():
            return 0
        return Comment.find_n_unread(user=user,
                                     node=obj.node,
                                     page='files',
                                     root_id=obj.get_guid()._id)

    def user_id(self, obj):
        # NOTE: obj is the user here, the meta field for
        # Hyperlinks is weird
        if obj:
            return obj._id
        return None

    def update(self, instance, validated_data):
        assert isinstance(instance, FileNode), 'Instance must be a FileNode'
        if instance.provider != 'osfstorage' and 'tags' in validated_data:
            raise Conflict(
                'File service provider {} does not support tags on the OSF.'.
                format(instance.provider))
        auth = get_user_auth(self.context['request'])
        old_tags = set([tag._id for tag in instance.tags])
        if 'tags' in validated_data:
            current_tags = set(validated_data.pop('tags', []))
        else:
            current_tags = set(old_tags)

        for new_tag in (current_tags - old_tags):
            instance.add_tag(new_tag, auth=auth)
        for deleted_tag in (old_tags - current_tags):
            instance.remove_tag(deleted_tag, auth=auth)

        for attr, value in validated_data.items():
            if attr == 'checkout':
                user = self.context['request'].user
                instance.check_in_or_out(user, value)
            else:
                setattr(instance, attr, value)
        instance.save()
        return instance

    def is_valid(self, **kwargs):
        return super(FileSerializer, self).is_valid(clean_html=False, **kwargs)

    def get_file_guid(self, obj):
        if obj:
            guid = obj.get_guid()
            if guid:
                return guid._id
        return None

    def get_absolute_url(self, obj):
        return api_v2_url('files/{}/'.format(obj._id))
コード例 #10
0
ファイル: serializers.py プロジェクト: ubiquitypress/osf.io
class FileSerializer(JSONAPISerializer):
    filterable_fields = frozenset([
        'id',
        'name',
        'node',
        'kind',
        'path',
        'size',
        'provider',
        'last_touched',
    ])
    id = IDField(source='_id', read_only=True)
    type = TypeField()
    checkout = CheckoutField()
    name = ser.CharField(read_only=True, help_text='Display name used in the general user interface')
    kind = ser.CharField(read_only=True, help_text='Either folder or file')
    path = ser.CharField(read_only=True, help_text='The unique path used to reference this object')
    size = ser.SerializerMethodField(read_only=True, help_text='The size of this file at this version')
    provider = ser.CharField(read_only=True, help_text='The Add-on service this file originates from')
    last_touched = ser.DateTimeField(read_only=True, help_text='The last time this file had information fetched about it via the OSF')
    date_modified = ser.SerializerMethodField(read_only=True, help_text='The size of this file at this version')
    extra = ser.SerializerMethodField(read_only=True, help_text='Additional metadata about this file')

    files = NodeFileHyperLinkField(
        related_view='nodes:node-files',
        related_view_kwargs={'node_id': '<node_id>', 'path': '<path>', 'provider': '<provider>'},
        kind='folder'
    )
    versions = NodeFileHyperLinkField(
        related_view='files:file-versions',
        related_view_kwargs={'file_id': '<_id>'},
        kind='file'
    )
    links = LinksField({
        'info': Link('files:file-detail', kwargs={'file_id': '<_id>'}),
        'move': WaterbutlerLink(),
        'upload': WaterbutlerLink(),
        'delete': WaterbutlerLink(),
        'download': WaterbutlerLink(must_be_file=True),
        'new_folder': WaterbutlerLink(must_be_folder=True, kind='folder'),
    })

    class Meta:
        type_ = 'files'

    def get_size(self, obj):
        if obj.versions:
            return obj.versions[-1].size
        return None

    def get_date_modified(self, obj):
        if obj.versions:
            if obj.provider == 'osfstorage':
                # Odd case osfstorage's date created is when the version was create
                # (when the file was modified) its date modified is referencing whatever backend it is on
                return obj.versions[-1].date_created
            return obj.versions[-1].date_modified
        return None

    def get_extra(self, obj):
        extras = {}
        if obj.versions:
            metadata = obj.versions[-1].metadata
            extras['hashes'] = {  # mimic waterbutler response
                'md5': metadata.get('md5', None),
                'sha256': metadata.get('sha256', None),
            }
        return extras

    def user_id(self, obj):
        # NOTE: obj is the user here, the meta field for
        # Hyperlinks is weird
        if obj:
            return obj._id
        return None

    def update(self, instance, validated_data):
        assert isinstance(instance, FileNode), 'Instance must be a FileNode'
        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        instance.save()
        return instance

    def is_valid(self, **kwargs):
        return super(FileSerializer, self).is_valid(clean_html=False, **kwargs)