Example #1
0
    def submit_deposit(self, pdf, form, dry_run=False):
        if self.repository.api_key is None:
            raise DepositError(__("No Zenodo API key provided."))
        api_key = self.repository.api_key
        api_url_with_key = self.api_url + '?access_token=' + api_key

        deposit_result = DepositResult()

        # Checking the access token
        self.log("### Checking the access token")
        r = requests.get(api_url_with_key)
        self.log_request(r, 200, __('Unable to authenticate to Zenodo.'))

        # Creating a new deposition
        self.log("### Creating a new deposition")
        headers = {"Content-Type": "application/json"}
        r = requests.post(api_url_with_key, data=str("{}"), headers=headers)
        self.log_request(r, 201,
                         __('Unable to create a new deposition on Zenodo.'))
        deposition_id = r.json()['id']
        deposit_result.identifier = deposition_id
        self.log("Deposition id: %d" % deposition_id)

        # Uploading the PDF
        self.log("### Uploading the PDF")
        data = {'name': 'article.pdf'}
        files = {'file': open(pdf, 'rb')}
        r = requests.post(self.api_url + "/%s/files?access_token=%s" %
                          (deposition_id, api_key),
                          data=data,
                          files=files)
        self.log_request(r, 201,
                         __('Unable to transfer the document to Zenodo.'))

        # Creating the metadata
        self.log("### Generating the metadata")
        data = self.createMetadata(form)
        self.log(json.dumps(data, indent=4) + '')

        # Check that there is an abstract
        if data['metadata'].get('description', '') == '':
            self.log('No abstract found, aborting.')
            raise DepositError(
                __('No abstract is available for this paper but ' +
                   'Zenodo requires to attach one. Please use the metadata panel to provide one.'
                   ))

        # Submitting the metadata
        self.log("### Submitting the metadata")
        r = requests.put(self.api_url + "/%s?access_token=%s" %
                         (deposition_id, api_key),
                         data=json.dumps(data),
                         headers=headers)
        self.log_request(r, 200,
                         __('Unable to submit paper metadata to Zenodo.'))

        if dry_run:
            # Deleting the deposition
            self.log("### Deleting the deposition")
            r = requests.delete(self.api_url + "/%s?access_token=%s" %
                                (deposition_id, api_key))
            self.log(r.text)
            deposit_result.status = 'faked'
            deposit_result.splash_url = 'http://sandbox.zenodo.org/fake'
            deposit_result.pdf_url = deposit_result.splash_url
        else:
            self.log("### Publishing the deposition")
            r = requests.post(self.api_url +
                              "/%s/actions/publish?access_token=%s" %
                              (deposition_id, api_key))
            self.log_request(r, 202,
                             __('Unable to publish the deposition on Zenodo.'))
            self.log(r.text)

            deposition_object = r.json()
            links = deposition_object.get('links', {})
            deposit_result.splash_url = links.get('record_html',
                                                  'https://zenodo.org/')
            deposit_result.pdf_url = deposit_result.splash_url + '/files/article.pdf'

        return deposit_result
Example #2
0
    def submit_deposit(self, pdf, form, dry_run=False):
        if not self.api_url:
            raise DepositError(_("No Repository endpoint provided."))

        if self.repository.api_key is None:
            raise DepositError(_("No OSF token provided."))

        api_key = self.repository.api_key
        self.license_id = form.cleaned_data['license'].transmit_id
        self.user_id_on_osf = self.get_preferences(self.user).on_behalf_of

        paper, abstract = self.get_primary_data(form)
        authors = paper['authors']
        records = paper['records']
        self.pub_date = paper['date'][:-6]
        tags = self.create_tags(form)
        subjects = self.create_subjects(form)

        deposit_result = DepositResult()

        # To connect to the API.
        self.headers = {
            'Authorization': 'Bearer %s' % api_key,
            'Content-Type': 'application/vnd.api+json'
        }
        self.user_id = self.repository.username

        # Creating the metadata.
        self.create_node(abstract, tags, authors)

        self.log("### Creating a new deposition")
        osf_storage_data = self.get_newnode_osf_storage(self.node_id)
        osf_links = osf_storage_data['data']
        osf_upload_link = str(
            list({self.translate_links(entry)
                  for entry in osf_links}))
        osf_upload_link = osf_upload_link.replace("[u'", '').replace("']", '')

        self.log("### Uploading the PDF")
        upload_url_suffix = "?kind=file&name=article.pdf"
        upload_url = osf_upload_link + upload_url_suffix
        data = open(pdf, 'r')
        primary_file_data = requests.put(upload_url,
                                         data=data,
                                         headers=self.headers)
        self.log_request(primary_file_data, 201,
                         _('Unable to upload the PDF file.'))
        primary_file_data = primary_file_data.json()

        pf_path = primary_file_data['data']['attributes']['path'][1:]

        self.add_contributors(authors)

        self.create_license(authors)

        # Create the Preprint.
        osf_preprint_response = (self.create_preprint(pf_path, records,
                                                      subjects))
        preprint_id = osf_preprint_response['data']['id']

        if self.api_url == "https://test-api.osf.io/":
            self.preprint_public_url = "https://test.osf.io/" + preprint_id
        else:
            self.preprint_public_url = "https://osf.io/" + preprint_id

        preprint_public_pdf = self.preprint_public_url + "/download"

        self.update_preprint_license(authors, preprint_id)
        self.mask_dissemin_contributor()

        if self.api_url == "https://test-api.osf.io/":
            self.project_public_url = "https://test.osf.io/" + self.node_id
        else:
            self.project_public_url = "https://osf.io/" + self.node_id

        self.log("### FINAL DEBUG")
        self.log(self.project_public_url)
        self.log(self.preprint_public_url)
        self.log(preprint_public_pdf)

        if dry_run:
            self.log("### Deleting the deposition")
            deletion_req = requests.delete(self.node_url, headers=self.headers)
            self.log_request(deletion_req, 204,
                             _('Unable to delete the project.'))
            self.log(str(deletion_req.status_code))
            self.log(deletion_req.text)
        else:
            self.log("### Publishing the deposition")
            public_project = {
                "data": {
                    "type": "nodes",
                    "id": self.node_id,
                    "attributes": {
                        "public": "true"
                    }
                }
            }

            public_preprint = {
                "type": "preprints",
                "data": {
                    "id": preprint_id,
                    "attributes": {
                        "is_published": "true"
                    }
                }
            }
            self.log("### Make the project public")
            project_pub_req = requests.patch(self.node_url,
                                             data=json.dumps(public_project),
                                             headers=self.headers)

            self.log_request(project_pub_req, 200,
                             _('Unable to make the project public.'))

            self.log("### Make the preprint public")
            preprint_pub_req = requests.patch(self.preprint_node_url,
                                              data=json.dumps(public_preprint),
                                              headers=self.headers)

            self.log_request(preprint_pub_req, 200,
                             _('Unable to make the project public.'))

        deposit_result.identifier = self.project_public_url
        deposit_result.splash_url = self.preprint_public_url
        deposit_result.pdf_url = preprint_public_pdf

        return deposit_result
Example #3
0
    def submit_deposit(self, pdf, form, dry_run=False):
        if self.username is None or self.password is None:
            raise DepositError(_("No HAL user credentials provided."))

        deposit_result = DepositResult()

        try:
            # Creating the metadata
            self.log("### Generating metadata")
            metadata = self.create_metadata(form)

            # Bundling the metadata and the PDF
            self.log("### Creating ZIP file")
            zipFile = self.create_zip(pdf, metadata)

            # Build the list of users who should own this deposit
            on_behalf_of = [self.username]
            if self.hal_preferences.on_behalf_of:
                on_behalf_of.append(self.hal_preferences.on_behalf_of)

            # Creating a new deposition
            self.log("### Creating a new deposition")

            parsed_endpoint = urlparse(self.api_url)
            host = parsed_endpoint.netloc
            path = parsed_endpoint.path + 'hal'

            conn = http_client.HTTPConnection(host)
            conn.putrequest('POST', path, True, True)
            zipContent = zipFile.getvalue()
            headers = {
                'Authorization': self.encodeUserData(),
                'Host': host,
                'X-Packaging': 'http://purl.org/net/sword-types/AOfr',
                'Content-Type': 'application/zip',
                'Content-Disposition': 'attachment; filename=meta.xml',
                'Content-Length': len(zipContent),
                'On-Behalf-Of': ';'.join(on_behalf_of),
                }
            for header, value in list(headers.items()):
                conn.putheader(header, value)
            conn.endheaders()
            conn.send(zipContent)
            resp = conn.getresponse()

            xml_response = resp.read()
            conn.close()
            try:
                parser = etree.XMLParser(encoding='utf-8')
                receipt = etree.parse(BytesIO(xml_response), parser)
                if resp.status != 201:
                    self.log('Deposit response status: HTTP %d' % resp.status)
                    self.log(xml_response.decode('utf-8'))
                    self.log('Metadata payload was:')
                    self.log(metadata.decode('utf-8'))
                    # Get the verbose description of the error to output it as well
                    root = receipt.getroot()
                    verboseDescription = (
                        next(
                            root.iter(
                                "{http://purl.org/net/sword/error/}verboseDescription"
                            )
                        ).text
                    )
                    try:
                        # Give a better error message to the user if the document
                        # already exists in HAL. See #356.
                        assert "duplicate-entry" in json.loads(verboseDescription)
                        raise DepositError(
                            _(
                                'This document is already in HAL. '
                                'HAL refused the deposit.'
                            )
                        )
                    except (ValueError, AssertionError):
                        raise DepositError(
                            _(
                                'HAL refused the deposit (HTTP error %d): %s') %
                                (resp.status, verboseDescription)
                            )
            except etree.XMLSyntaxError:
                self.log('Invalid XML response from HAL:')
                self.log(xml_response.decode('utf-8'))
                self.log('(end of the response)')
                raise DepositError(_('HAL returned an invalid XML response'))

            receipt = receipt.getroot()
            if receipt.tag == '{http://purl.org/net/sword/error/}error':
                self.log('Error while depositing the content.')
                verbosedesc = receipt.find(
                    '{http://purl.org/net/sword/error/}verboseDescription')

                # this will happen if a paper has not made its way via
                # OAI to us, so we could not detect that earlier in the
                # submission
                if verbosedesc is not None and 'duplicate-entry' in verbosedesc.text:
                    raise DepositError(_('This paper already exists in HAL.'))

                # Otherwise this error should not happen: let's dump
                # everything to check later
                self.log('Here is the XML response:{}'.format(xml_response.decode('utf-8')))
                self.log('Here is the metadata:{}'.format(metadata.decode('utf-8')))
                raise DepositError(_('HAL rejected the submission.'))
            else:
                self.log(xml_response.decode('utf-8'))

            deposition_id = receipt.find('{http://www.w3.org/2005/Atom}id').text
            password = receipt.find(
                '{http://hal.archives-ouvertes.fr/}password').text
            document_url = resp.getheader('location')

            if not deposition_id:
                raise DepositError(_('HAL rejected the submission'))

            self.log("Deposition id: %s" % deposition_id)

            deposit_result.identifier = deposition_id
            deposit_result.splash_url = document_url
            deposit_result.pdf_url = None
            deposit_result.status = 'pending' # HAL moderates submissions
            deposit_result.additional_info = [
                {'label':_('Password'),
                 'value':password},
            ]

            if dry_run:
                conn = http_client.HTTPConnection(host)
                conn.putrequest('DELETE', '/sword/'+deposition_id)
                headers = {
                    'Authorization': self.encodeUserData(),
                   # 'Host': host,
                    'Accept': '*/*',
                    'User-Agent': 'dissemin',
                }
                for header, value in list(headers.items()):
                    conn.putheader(header, value)
                conn.endheaders()
                resp = conn.getresponse()
                self.log(resp.read())
                conn.close()
                deposit_result.status = 'faked'

        except DepositError as e:
            raise e
        except Exception as e:
            self.log("Caught exception:")
            self.log(str(type(e))+': '+str(e)+'')
            self.log(traceback.format_exc())
            raise DepositError(_(
                'Connection to HAL failed. Please try again later.'))

        return deposit_result
Example #4
0
    def submit_deposit(self, pdf, form, dry_run=False):
        if self.username is None or self.password is None:
            raise DepositError(_("No HAL user credentials provided."))

        deposit_result = DepositResult()

        try:
            # Creating the metadata
            self.log("### Generating metadata")
            metadata = self.create_metadata(form)

            # Bundling the metadata and the PDF
            self.log("### Creating ZIP file")
            zipFile = self.create_zip(pdf, metadata)

            # Build the list of users who should own this deposit
            on_behalf_of = [self.username]
            if self.hal_preferences.on_behalf_of:
                on_behalf_of.append(self.hal_preferences.on_behalf_of)

            # Creating a new deposition
            self.log("### Creating a new deposition")

            parsed_endpoint = urlparse(self.api_url)
            host = parsed_endpoint.netloc
            path = parsed_endpoint.path + 'hal'

            if self.api_url.startswith('http://'):
                conn = http_client.HTTPConnection(host)
            else:
                conn = http_client.HTTPSConnection(host)
            conn.putrequest('POST', path, True, True)
            zipContent = zipFile.getvalue()
            headers = {
                'Authorization': self.encodeUserData(),
                'Host': host,
                'X-Packaging': 'http://purl.org/net/sword-types/AOfr',
                'Content-Type': 'application/zip',
                'Content-Disposition': 'attachment; filename=meta.xml',
                'Content-Length': len(zipContent),
                'On-Behalf-Of': ';'.join(on_behalf_of),
            }
            for header, value in list(headers.items()):
                conn.putheader(header, value)
            conn.endheaders()
            conn.send(zipContent)
            resp = conn.getresponse()

            xml_response = resp.read()
            conn.close()
            try:
                parser = etree.XMLParser(encoding='utf-8')
                receipt = etree.parse(BytesIO(xml_response), parser)
                if resp.status != 201:
                    self.log('Deposit response status: HTTP %d' % resp.status)
                    self.log(xml_response.decode('utf-8'))
                    self.log('Metadata payload was:')
                    self.log(metadata.decode('utf-8'))
                    # Get the verbose description of the error to output it as well
                    root = receipt.getroot()
                    verboseDescription = (next(
                        root.iter(
                            "{http://purl.org/net/sword/error/}verboseDescription"
                        )).text)
                    try:
                        # Give a better error message to the user if the document
                        # already exists in HAL. See #356.
                        assert "duplicate-entry" in json.loads(
                            verboseDescription)
                        raise DepositError(
                            _('This document is already in HAL. '
                              'HAL refused the deposit.'))
                    except (ValueError, AssertionError):
                        raise DepositError(
                            _('HAL refused the deposit (HTTP error %d): %s') %
                            (resp.status, verboseDescription))
            except etree.XMLSyntaxError:
                self.log('Invalid XML response from HAL:')
                self.log(xml_response.decode('utf-8'))
                self.log('(end of the response)')
                raise DepositError(_('HAL returned an invalid XML response'))

            receipt = receipt.getroot()
            if receipt.tag == '{http://purl.org/net/sword/error/}error':
                self.log('Error while depositing the content.')
                verbosedesc = receipt.find(
                    '{http://purl.org/net/sword/error/}verboseDescription')

                # this will happen if a paper has not made its way via
                # OAI to us, so we could not detect that earlier in the
                # submission
                if verbosedesc is not None and 'duplicate-entry' in verbosedesc.text:
                    raise DepositError(_('This paper already exists in HAL.'))

                # Otherwise this error should not happen: let's dump
                # everything to check later
                self.log('Here is the XML response:{}'.format(
                    xml_response.decode('utf-8')))
                self.log('Here is the metadata:{}'.format(
                    metadata.decode('utf-8')))
                raise DepositError(_('HAL rejected the submission.'))
            else:
                self.log(xml_response.decode('utf-8'))

            deposition_id = receipt.find(
                '{http://www.w3.org/2005/Atom}id').text
            password = receipt.find(
                '{http://hal.archives-ouvertes.fr/}password').text
            document_url = resp.getheader('location')

            if not deposition_id:
                raise DepositError(_('HAL rejected the submission'))

            self.log("Deposition id: %s" % deposition_id)

            deposit_result.identifier = deposition_id
            deposit_result.splash_url = document_url
            deposit_result.pdf_url = None
            deposit_result.status = 'pending'  # HAL moderates submissions
            deposit_result.additional_info = [
                {
                    'label': _('Password'),
                    'value': password
                },
            ]

            if dry_run:
                conn = http_client.HTTPConnection(host)
                conn.putrequest('DELETE', '/sword/' + deposition_id)
                headers = {
                    'Authorization': self.encodeUserData(),
                    # 'Host': host,
                    'Accept': '*/*',
                    'User-Agent': 'dissemin',
                }
                for header, value in list(headers.items()):
                    conn.putheader(header, value)
                conn.endheaders()
                resp = conn.getresponse()
                self.log(resp.read())
                conn.close()
                deposit_result.status = 'faked'

        except DepositError as e:
            raise e
        except Exception as e:
            self.log("Caught exception:")
            self.log(str(type(e)) + ': ' + str(e) + '')
            self.log(traceback.format_exc())
            raise DepositError(
                _('Connection to HAL failed. Please try again later.'))

        return deposit_result
Example #5
0
    def submit_deposit(self, pdf, form, dry_run=False):
        if not self.api_url:
            raise DepositError(_("No Repository endpoint provided."))

        if self.repository.api_key is None:
            raise DepositError(_("No OSF token provided."))

        api_key = self.repository.api_key
        self.license_id = form.cleaned_data['license']
        self.user_id_on_osf = self.get_preferences(self.user).on_behalf_of

        paper, abstract = self.get_primary_data(form)
        authors = paper['authors']
        records = paper['records']
        self.pub_date = paper['date'][:-6]
        tags = self.create_tags(form)
        subjects = self.create_subjects(form)

        deposit_result = DepositResult()

        # To connect to the API.
        self.headers = {
            'Authorization': 'Bearer %s' % api_key,
            'Content-Type': 'application/vnd.api+json'
        }
        self.user_id = self.repository.username

        # Creating the metadata.
        self.create_node(abstract, tags, authors)

        self.log("### Creating a new deposition")
        osf_storage_data = self.get_newnode_osf_storage(self.node_id)
        osf_links = osf_storage_data['data']
        osf_upload_link = str(
            list({self.translate_links(entry) for entry in osf_links})
        )
        osf_upload_link = osf_upload_link.replace("[u'", '').replace("']", '')

        self.log("### Uploading the PDF")
        upload_url_suffix = "?kind=file&name=article.pdf"
        upload_url = osf_upload_link + upload_url_suffix
        data = open(pdf, 'r')
        primary_file_data = requests.put(upload_url,
                                         data=data,
                                         headers=self.headers)
        self.log_request(primary_file_data, 201,
                         _('Unable to upload the PDF file.'))
        primary_file_data = primary_file_data.json()

        pf_path = primary_file_data['data']['attributes']['path'][1:]

        self.add_contributors(authors)

        self.create_license(authors)

        # Create the Preprint.
        osf_preprint_response = (
            self.create_preprint(pf_path, records, subjects)
        )
        preprint_id = osf_preprint_response['data']['id']

        if self.api_url == "https://test-api.osf.io/":
            self.preprint_public_url = "https://test.osf.io/" + preprint_id
        else:
            self.preprint_public_url = "https://osf.io/" + preprint_id

        preprint_public_pdf = self.preprint_public_url + "/download"

        self.update_preprint_license(authors, preprint_id)
        self.mask_dissemin_contributor()

        if self.api_url == "https://test-api.osf.io/":
            self.project_public_url = "https://test.osf.io/" + self.node_id
        else:
            self.project_public_url = "https://osf.io/" + self.node_id

        self.log("### FINAL DEBUG")
        self.log(self.project_public_url)
        self.log(self.preprint_public_url)
        self.log(preprint_public_pdf)

        if dry_run:
            self.log("### Deleting the deposition")
            deletion_req = requests.delete(self.node_url,
                                           headers=self.headers)
            self.log_request(deletion_req, 204,
                             _('Unable to delete the project.'))
            self.log(str(deletion_req.status_code))
            self.log(deletion_req.text)
        else:
            self.log("### Publishing the deposition")
            public_project = {
                "data": {
                    "type": "nodes",
                    "id": self.node_id,
                    "attributes": {
                        "public": "true"
                    }
                }
            }

            public_preprint = {
                "type": "preprints",
                "data": {
                    "id": preprint_id,
                    "attributes": {
                        "is_published": "true"
                    }
                }
            }
            self.log("### Make the project public")
            project_pub_req = requests.patch(self.node_url,
                                             data=json.dumps(public_project),
                                             headers=self.headers)

            self.log_request(project_pub_req, 200,
                             _('Unable to make the project public.'))

            self.log("### Make the preprint public")
            preprint_pub_req = requests.patch(self.preprint_node_url,
                                              data=json.dumps(public_preprint),
                                              headers=self.headers)

            self.log_request(preprint_pub_req, 200,
                             _('Unable to make the project public.'))

        deposit_result.identifier = self.project_public_url
        deposit_result.splash_url = self.preprint_public_url
        deposit_result.pdf_url = preprint_public_pdf

        return deposit_result
Example #6
0
    def submit_deposit(self, pdf, form, dry_run=False):
        if self.repository.api_key is None:
            raise DepositError(_("No Zenodo API key provided."))
        api_key = self.repository.api_key
        api_url_with_key = self.api_url+'?access_token='+api_key

        deposit_result = DepositResult()

        # Checking the access token
        self.log("### Checking the access token")
        r = requests.get(api_url_with_key)
        hiccups_message = ' ' + _(
            'This happens when Zenodo has hiccups. '
            'Please try again in a few minutes or use a different '
            'repository in the menu above.'
        )
        self.log_request(
            r, 200,
            _('Unable to authenticate to Zenodo.') + hiccups_message
        )

        # Creating a new deposition
        self.log("### Creating a new deposition")
        headers = {"Content-Type": "application/json"}
        r = requests.post(api_url_with_key, data=str("{}"), headers=headers)
        self.log_request(r, 201, _(
            'Unable to create a new deposition on Zenodo.')+hiccups_message)
        deposition_id = r.json()['id']
        deposit_result.identifier = deposition_id
        self.log("Deposition id: %d" % deposition_id)

        # Uploading the PDF
        self.log("### Uploading the PDF")
        data = {'name': 'article.pdf'}
        files = {'file': open(pdf, 'rb')}
        r = requests.post(
            (
                self.api_url + "/%s/files?access_token=%s" %
                (deposition_id, api_key)
            ),
            data=data, files=files
        )
        self.log_request(r, 201, _(
            'Unable to transfer the document to Zenodo.')+hiccups_message)

        # Creating the metadata
        self.log("### Generating the metadata")
        data = self.createMetadata(form)
        self.log(json.dumps(data, indent=4)+'')

        # Check that there is an abstract
        if data['metadata'].get('description', '') == '':
            self.log('No abstract found, aborting.')
            raise DepositError(_(
                'No abstract is available for this paper but Zenodo '
                'requires one. Please provide it using the metadata panel.'
            ))

        # Submitting the metadata
        self.log("### Submitting the metadata")
        r = requests.put(
            self.api_url + "/%s?access_token=%s" % (deposition_id, api_key),
            data=json.dumps(data),
            headers=headers
        )
        self.log_request(r, 200, _(
            'Unable to submit paper metadata to Zenodo.'))

        if dry_run:
            # Deleting the deposition
            self.log("### Deleting the deposition")
            r = requests.delete(self.api_url+"/%s?access_token=%s" %
                                (deposition_id, api_key))
            self.log(r.text)
            deposit_result.status = 'faked'
            deposit_result.splash_url = 'http://sandbox.zenodo.org/fake'
            deposit_result.pdf_url = deposit_result.splash_url
        else:
            self.log("### Publishing the deposition")
            r = requests.post(
                self.api_url + "/%s/actions/publish?access_token=%s" %
                (deposition_id, api_key)
            )
            self.log_request(r, 202, _(
                'Unable to publish the deposition on Zenodo.'))
            self.log(r.text)

            deposition_object = r.json()
            links = deposition_object.get('links', {})
            deposit_result.splash_url = links.get(
                'record_html', 'https://zenodo.org/'
            )
            deposit_result.pdf_url = (
                deposit_result.splash_url + '/files/article.pdf'
            )

        return deposit_result