コード例 #1
0
    def create(self, validated_data):
        node = validated_data.pop('node', {})
        if isinstance(node, dict):
            node = Node.objects.create(creator=self.context['request'].user,
                                       **node)

        if node.is_deleted:
            raise exceptions.ValidationError(
                'Cannot create a preprint from a deleted node.')

        auth = get_user_auth(self.context['request'])
        if not node.has_permission(auth.user, permissions.ADMIN):
            raise exceptions.PermissionDenied

        provider = validated_data.pop('provider', None)
        if not provider:
            raise exceptions.ValidationError(
                detail='You must specify a valid provider to create a preprint.'
            )

        node_preprints = node.preprints.filter(provider=provider)
        if node_preprints.exists():
            raise Conflict(
                'Only one preprint per provider can be submitted for a node. Check `meta[existing_resource_id]`.',
                meta={'existing_resource_id': node_preprints.first()._id})

        preprint = PreprintService(node=node, provider=provider)
        preprint.save()
        preprint.node._has_abandoned_preprint = True
        preprint.node.save()

        return self.update(preprint, validated_data)
コード例 #2
0
ファイル: serializers.py プロジェクト: erinspace/osf.io
    def create(self, validated_data):
        node = validated_data.pop('node', {})
        if isinstance(node, dict):
            node = Node.objects.create(creator=self.context['request'].user, **node)

        if node.is_deleted:
            raise exceptions.ValidationError('Cannot create a preprint from a deleted node.')

        auth = get_user_auth(self.context['request'])
        if not node.has_permission(auth.user, permissions.ADMIN):
            raise exceptions.PermissionDenied

        provider = validated_data.pop('provider', None)
        if not provider:
            raise exceptions.ValidationError(detail='You must specify a valid provider to create a preprint.')

        node_preprints = node.preprints.filter(provider=provider)
        if node_preprints.exists():
            raise Conflict('Only one preprint per provider can be submitted for a node. Check `meta[existing_resource_id]`.', meta={'existing_resource_id': node_preprints.first()._id})

        preprint = PreprintService(node=node, provider=provider)
        preprint.save()
        preprint.node._has_abandoned_preprint = True
        preprint.node.save()

        return self.update(preprint, validated_data)
コード例 #3
0
ファイル: serializers.py プロジェクト: adlius/osf.io
    def create(self, validated_data):
        node = validated_data.pop('node', None)
        if not node:
            raise exceptions.NotFound('Unable to find Node with specified id.')
        elif node.is_deleted:
            raise exceptions.ValidationError('Cannot create a preprint from a deleted node.')

        auth = get_user_auth(self.context['request'])
        if not node.has_permission(auth.user, permissions.ADMIN):
            raise exceptions.PermissionDenied

        primary_file = validated_data.pop('primary_file', None)
        if not primary_file:
            raise exceptions.ValidationError(detail='You must specify a valid primary_file to create a preprint.')

        provider = validated_data.pop('provider', None)
        if not provider:
            raise exceptions.ValidationError(detail='You must specify a valid provider to create a preprint.')

        if PreprintService.find(Q('node', 'eq', node) & Q('provider', 'eq', provider)).count():
            conflict = PreprintService.find_one(Q('node', 'eq', node) & Q('provider', 'eq', provider))
            raise Conflict('Only one preprint per provider can be submitted for a node. Check `meta[existing_resource_id]`.', meta={'existing_resource_id': conflict._id})

        preprint = PreprintService(node=node, provider=provider)
        self.set_field(preprint.set_primary_file, primary_file, auth, save=True)
        preprint.node._has_abandoned_preprint = True
        preprint.node.save()

        return self.update(preprint, validated_data)
コード例 #4
0
ファイル: tasks.py プロジェクト: adlius/osf.io
def on_preprint_updated(preprint_id, update_share=True):
    # WARNING: Only perform Read-Only operations in an asynchronous task, until Repeatable Read/Serializable
    # transactions are implemented in View and Task application layers.
    from osf.models import PreprintService
    preprint = PreprintService.load(preprint_id)

    if preprint.node:
        status = 'public' if preprint.node.is_public else 'unavailable'
        try:
            update_ezid_metadata_on_change(preprint, status=status)
        except HTTPError as err:
            sentry.log_exception()
            sentry.log_message(err.args[0])

    if settings.SHARE_URL and update_share:
        if not preprint.provider.access_token:
            raise ValueError('No access_token for {}. Unable to send {} to SHARE.'.format(preprint.provider, preprint))
        resp = requests.post('{}api/v2/normalizeddata/'.format(settings.SHARE_URL), json={
            'data': {
                'type': 'NormalizedData',
                'attributes': {
                    'tasks': [],
                    'raw': None,
                    'data': {'@graph': format_preprint(preprint)}
                }
            }
        }, headers={'Authorization': 'Bearer {}'.format(preprint.provider.access_token), 'Content-Type': 'application/vnd.api+json'})
        logger.debug(resp.content)
        resp.raise_for_status()
コード例 #5
0
def on_preprint_updated(preprint_id):
    # WARNING: Only perform Read-Only operations in an asynchronous task, until Repeatable Read/Serializable
    # transactions are implemented in View and Task application layers.
    from osf.models import PreprintService
    preprint = PreprintService.load(preprint_id)

    if settings.SHARE_URL:
        if not preprint.provider.access_token:
            raise ValueError(
                'No access_token for {}. Unable to send {} to SHARE.'.format(
                    preprint.provider, preprint))
        resp = requests.post(
            '{}api/v2/normalizeddata/'.format(settings.SHARE_URL),
            json={
                'data': {
                    'type': 'NormalizedData',
                    'attributes': {
                        'tasks': [],
                        'raw': None,
                        'data': {
                            '@graph': format_preprint(preprint)
                        }
                    }
                }
            },
            headers={
                'Authorization':
                'Bearer {}'.format(preprint.provider.access_token),
                'Content-Type': 'application/vnd.api+json'
            })
        logger.debug(resp.content)
        resp.raise_for_status()
コード例 #6
0
ファイル: tasks.py プロジェクト: chriskaschner/osf.io
def _async_update_preprint_share(self, preprint_id, old_subjects, share_type):
    # Any modifications to this function may need to change _update_preprint_share
    # Takes preprint_id to ensure async retries push fresh data
    PreprintService = apps.get_model('osf.PreprintService')
    preprint = PreprintService.load(preprint_id)

    data = serialize_share_preprint_data(preprint, share_type, old_subjects)
    resp = send_share_preprint_data(preprint, data)
    try:
        resp = requests.post('{}api/v2/normalizeddata/'.format(settings.SHARE_URL), json={
            'data': {
                'type': 'NormalizedData',
                'attributes': {
                    'tasks': [],
                    'raw': None,
                    'data': {'@graph': format_preprint(preprint, share_type, old_subjects)}
                }
            }
        }, headers={'Authorization': 'Bearer {}'.format(preprint.provider.access_token), 'Content-Type': 'application/vnd.api+json'})
        logger.debug(resp.content)
        resp.raise_for_status()
    except Exception as e:
        if resp.status_code >= 500:
            if self.request.retries == self.max_retries:
                send_desk_share_preprint_error(preprint, resp, self.request.retries)
            raise self.retry(
                exc=e,
                countdown=(random.random() + 1) * min(60 + settings.CELERY_RETRY_BACKOFF_BASE ** self.request.retries, 60 * 10)
            )
        else:
            send_desk_share_preprint_error(preprint, resp, self.request.retries)
コード例 #7
0
ファイル: tasks.py プロジェクト: mfraezz/osf.io
def _async_update_preprint_share(self, preprint_id, old_subjects, share_type):
    # Any modifications to this function may need to change _update_preprint_share
    # Takes preprint_id to ensure async retries push fresh data
    PreprintService = apps.get_model('osf.PreprintService')
    preprint = PreprintService.load(preprint_id)

    data = serialize_share_preprint_data(preprint, share_type, old_subjects)
    resp = send_share_preprint_data(preprint, data)
    try:
        resp = requests.post('{}api/v2/normalizeddata/'.format(settings.SHARE_URL), json={
            'data': {
                'type': 'NormalizedData',
                'attributes': {
                    'tasks': [],
                    'raw': None,
                    'data': {'@graph': format_preprint(preprint, share_type, old_subjects)}
                }
            }
        }, headers={'Authorization': 'Bearer {}'.format(preprint.provider.access_token), 'Content-Type': 'application/vnd.api+json'})
        logger.debug(resp.content)
        resp.raise_for_status()
    except Exception as e:
        if resp.status_code >= 500:
            if self.request.retries == self.max_retries:
                send_desk_share_preprint_error(preprint, resp, self.request.retries)
            raise self.retry(
                exc=e,
                countdown=(random.random() + 1) * min(60 + settings.CELERY_RETRY_BACKOFF_BASE ** self.request.retries, 60 * 10)
            )
        else:
            send_desk_share_preprint_error(preprint, resp, self.request.retries)
コード例 #8
0
ファイル: tasks.py プロジェクト: adlius/osf.io
def get_and_set_preprint_identifiers(preprint_id):
    from osf.models import PreprintService

    preprint = PreprintService.load(preprint_id)
    ezid_response = request_identifiers_from_ezid(preprint)
    id_dict = parse_identifiers(ezid_response)
    preprint.set_identifier_values(doi=id_dict['doi'], ark=id_dict['ark'])
コード例 #9
0
ファイル: tasks.py プロジェクト: mfraezz/osf.io
def get_and_set_preprint_identifiers(preprint_id):
    PreprintService = apps.get_model('osf.PreprintService')
    preprint = PreprintService.load(preprint_id)
    ezid_response = request_identifiers_from_ezid(preprint)
    if ezid_response is None:
        return
    id_dict = parse_identifiers(ezid_response)
    preprint.set_identifier_values(doi=id_dict['doi'], save=True)
コード例 #10
0
ファイル: tasks.py プロジェクト: chriskaschner/osf.io
def get_and_set_preprint_identifiers(preprint_id):
    PreprintService = apps.get_model('osf.PreprintService')
    preprint = PreprintService.load(preprint_id)
    ezid_response = request_identifiers_from_ezid(preprint)
    if ezid_response is None:
        return
    id_dict = parse_identifiers(ezid_response)
    preprint.set_identifier_values(doi=id_dict['doi'], ark=id_dict['ark'], save=True)
コード例 #11
0
ファイル: serializers.py プロジェクト: mfraezz/osf.io
 def get_preprint_provider(self, obj):
     preprint_id = obj.get('preprint', None)
     if preprint_id:
         preprint = PreprintService.load(preprint_id)
         if preprint:
             provider = preprint.provider
             return {'url': provider.external_url, 'name': provider.name}
     return None
コード例 #12
0
ファイル: serializers.py プロジェクト: h-ci-user01/osf.h-test
 def get_preprint_provider(self, obj):
     preprint_id = obj.get('preprint', None)
     if preprint_id:
         preprint = PreprintService.load(preprint_id)
         if preprint:
             provider = preprint.provider
             return {'url': provider.external_url, 'name': provider.name}
     return None
コード例 #13
0
    def post(self, request):
        crossref_email_content = lxml.etree.fromstring(str(request.POST['body-plain']))
        status = crossref_email_content.get('status').lower()  # from element doi_batch_diagnostic
        record_count = int(crossref_email_content.find('batch_data/record_count').text)
        records = crossref_email_content.xpath('//record_diagnostic')
        dois_processed = 0

        if status == 'completed':
            guids = []
            # Keep track of errors recieved, ignore those that are handled
            unexpected_errors = False
            for record in records:
                doi = getattr(record.find('doi'), 'text', None)
                guid = doi.split('/')[-1] if doi else None
                guids.append(guid)
                preprint = PreprintService.load(guid) if guid else None
                if record.get('status').lower() == 'success' and doi:
                    msg = record.find('msg').text
                    created = bool(msg == 'Successfully added')
                    legacy_doi = preprint.get_identifier(category='legacy_doi')
                    if created or legacy_doi:
                        # Sets preprint_doi_created and saves the preprint
                        preprint.set_identifier_values(doi=doi, save=True)
                    # Double records returned when possible matching DOI is found in crossref
                    elif 'possible preprint/vor pair' not in msg.lower():
                        # Directly updates the identifier
                        preprint.set_identifier_value(category='doi', value=doi)

                    dois_processed += 1

                    # Mark legacy DOIs overwritten by newly batch confirmed crossref DOIs
                    if legacy_doi:
                        legacy_doi.remove()

                elif record.get('status').lower() == 'failure':
                    if 'Relation target DOI does not exist' in record.find('msg').text:
                        logger.warn('Related publication DOI does not exist, sending metadata again without it...')
                        client = preprint.get_doi_client()
                        client.create_identifier(preprint, category='doi', include_relation=False)
                    # This error occurs when a single preprint is being updated several times in a row with the same metadata [#PLAT-944]
                    elif 'less or equal to previously submitted version' in record.find('msg').text and record_count == 2:
                        break
                    else:
                        unexpected_errors = True
            logger.info('Creation success email received from CrossRef for preprints: {}'.format(guids))

        if dois_processed != record_count or status != 'completed':
            if unexpected_errors:
                batch_id = crossref_email_content.find('batch_id').text
                mails.send_mail(
                    to_addr=settings.OSF_SUPPORT_EMAIL,
                    mail=mails.CROSSREF_ERROR,
                    batch_id=batch_id,
                    email_content=request.POST['body-plain'],
                )
                logger.error('Error submitting metadata for batch_id {} with CrossRef, email sent to help desk'.format(batch_id))

        return HttpResponse('Mail received', status=200)
コード例 #14
0
ファイル: tasks.py プロジェクト: icereval/osf.io
def on_preprint_updated(preprint_id, update_share=True, share_type=None, old_subjects=None, saved_fields=None):
    # WARNING: Only perform Read-Only operations in an asynchronous task, until Repeatable Read/Serializable
    # transactions are implemented in View and Task application layers.
    from osf.models import PreprintService
    preprint = PreprintService.load(preprint_id)
    if old_subjects is None:
        old_subjects = []
    if should_update_preprint_identifiers(preprint, old_subjects, saved_fields):
        update_or_create_preprint_identifiers(preprint)
    if update_share:
        update_preprint_share(preprint, old_subjects, share_type)
コード例 #15
0
ファイル: serializers.py プロジェクト: BRosenblatt/osf.io
    def create(self, validated_data):
        node = validated_data.pop('node', None)
        if not node:
            raise exceptions.NotFound('Unable to find Node with specified id.')
        elif node.is_deleted:
            raise exceptions.ValidationError(
                'Cannot create a preprint from a deleted node.')

        auth = get_user_auth(self.context['request'])
        if not node.has_permission(auth.user, permissions.ADMIN):
            raise exceptions.PermissionDenied

        primary_file = validated_data.pop('primary_file', None)
        if not primary_file:
            raise exceptions.ValidationError(
                detail=
                'You must specify a valid primary_file to create a preprint.')

        provider = validated_data.pop('provider', None)
        if not provider:
            raise exceptions.ValidationError(
                detail='You must specify a valid provider to create a preprint.'
            )

        if PreprintService.find(
                Q('node', 'eq', node) & Q('provider', 'eq', provider)).count():
            conflict = PreprintService.find_one(
                Q('node', 'eq', node) & Q('provider', 'eq', provider))
            raise Conflict(
                'Only one preprint per provider can be submitted for a node. Check `meta[existing_resource_id]`.',
                meta={'existing_resource_id': conflict._id})

        preprint = PreprintService(node=node, provider=provider)
        self.set_field(preprint.set_primary_file,
                       primary_file,
                       auth,
                       save=True)
        preprint.node._has_abandoned_preprint = True
        preprint.node.save()

        return self.update(preprint, validated_data)
コード例 #16
0
def on_preprint_updated(preprint_id,
                        update_share=True,
                        share_type=None,
                        old_subjects=None):
    # WARNING: Only perform Read-Only operations in an asynchronous task, until Repeatable Read/Serializable
    # transactions are implemented in View and Task application layers.
    from osf.models import PreprintService
    preprint = PreprintService.load(preprint_id)
    if old_subjects is None:
        old_subjects = []
    if preprint.node:
        update_or_create_preprint_identifiers(preprint)
    if update_share:
        update_preprint_share(preprint, old_subjects, share_type)
コード例 #17
0
ファイル: tasks.py プロジェクト: chriskaschner/osf.io
def on_preprint_updated(preprint_id, update_share=True, share_type=None, old_subjects=None):
    # WARNING: Only perform Read-Only operations in an asynchronous task, until Repeatable Read/Serializable
    # transactions are implemented in View and Task application layers.
    from osf.models import PreprintService
    preprint = PreprintService.load(preprint_id)
    if old_subjects is None:
        old_subjects = []
    if preprint.node:
        status = 'public' if preprint.verified_publishable else 'unavailable'
        try:
            update_ezid_metadata_on_change(preprint._id, status=status)
        except HTTPError as err:
            sentry.log_exception()
            sentry.log_message(err.args[0])
    if update_share:
        update_preprint_share(preprint, old_subjects, share_type)
コード例 #18
0
 def test_create_preprint_adds_log_if_published(self, mock_get_identifiers):
     public_project_payload = build_preprint_create_payload(
         self.public_project._id, self.provider._id,
         self.file_one_public_project._id, {
             'is_published': True,
             'subjects': [[SubjectFactory()._id]],
         })
     res = self.app.post_json_api(self.url,
                                  public_project_payload,
                                  auth=self.user.auth)
     assert_equal(res.status_code, 201)
     preprint_id = res.json['data']['id']
     preprint = PreprintService.load(preprint_id)
     log = preprint.node.logs.latest()
     assert_equal(log.action, 'preprint_initiated')
     assert_equal(log.params.get('preprint'), preprint_id)
コード例 #19
0
ファイル: tasks.py プロジェクト: mfraezz/osf.io
def on_preprint_updated(preprint_id, update_share=True, share_type=None, old_subjects=None):
    # WARNING: Only perform Read-Only operations in an asynchronous task, until Repeatable Read/Serializable
    # transactions are implemented in View and Task application layers.
    from osf.models import PreprintService
    preprint = PreprintService.load(preprint_id)
    if old_subjects is None:
        old_subjects = []
    if preprint.node:
        status = 'public' if preprint.verified_publishable else 'unavailable'
        try:
            update_ezid_metadata_on_change(preprint._id, status=status)
        except HTTPError as err:
            sentry.log_exception()
            sentry.log_message(err.args[0])
    if update_share:
        update_preprint_share(preprint, old_subjects, share_type)
コード例 #20
0
ファイル: test_preprint_list.py プロジェクト: adlius/osf.io
 def test_create_preprint_adds_log_if_published(self):
     public_project_payload = build_preprint_create_payload(
         self.public_project._id,
         self.provider._id,
         self.file_one_public_project._id,
         {
             'is_published': True,
             'subjects': [[SubjectFactory()._id]],
         }
     )
     res = self.app.post_json_api(self.url, public_project_payload, auth=self.user.auth)
     assert_equal(res.status_code, 201)
     preprint_id = res.json['data']['id']
     preprint = PreprintService.load(preprint_id)
     log = preprint.node.logs.latest()
     assert_equal(log.action, 'preprint_initiated')
     assert_equal(log.params.get('preprint'), preprint_id)
コード例 #21
0
ファイル: tasks.py プロジェクト: icereval/osf.io
def _async_update_preprint_share(self, preprint_id, old_subjects, share_type):
    # Any modifications to this function may need to change _update_preprint_share
    # Takes preprint_id to ensure async retries push fresh data
    PreprintService = apps.get_model('osf.PreprintService')
    preprint = PreprintService.load(preprint_id)

    data = serialize_share_preprint_data(preprint, share_type, old_subjects)
    resp = send_share_preprint_data(preprint, data)
    try:
        resp.raise_for_status()
    except Exception as e:
        if resp.status_code >= 500:
            if self.request.retries == self.max_retries:
                send_desk_share_preprint_error(preprint, resp, self.request.retries)
            raise self.retry(
                exc=e,
                countdown=(random.random() + 1) * min(60 + settings.CELERY_RETRY_BACKOFF_BASE ** self.request.retries, 60 * 10)
            )
        else:
            send_desk_share_preprint_error(preprint, resp, self.request.retries)
コード例 #22
0
def _async_update_preprint_share(self, preprint_id, old_subjects, share_type):
    # Any modifications to this function may need to change _update_preprint_share
    # Takes preprint_id to ensure async retries push fresh data
    PreprintService = apps.get_model('osf.PreprintService')
    preprint = PreprintService.load(preprint_id)

    data = serialize_share_preprint_data(preprint, share_type, old_subjects)
    resp = send_share_preprint_data(preprint, data)
    try:
        resp.raise_for_status()
    except Exception as e:
        if resp.status_code >= 500:
            if self.request.retries == self.max_retries:
                send_desk_share_preprint_error(preprint, resp,
                                               self.request.retries)
            raise self.retry(exc=e,
                             countdown=(random.random() + 1) * min(
                                 60 + settings.CELERY_RETRY_BACKOFF_BASE**
                                 self.request.retries, 60 * 10))
        else:
            send_desk_share_preprint_error(preprint, resp,
                                           self.request.retries)
コード例 #23
0
ファイル: views.py プロジェクト: mfraezz/osf.io
 def perform_destroy(self, instance):
     if instance.is_published:
         raise Conflict('Published preprints cannot be deleted.')
     PreprintService.delete(instance)
コード例 #24
0
ファイル: views.py プロジェクト: slamdunking/osf.io
 def perform_destroy(self, instance):
     if instance.is_published:
         raise Conflict('Published preprints cannot be deleted.')
     PreprintService.delete(instance)