def _get_deposit_result(self, response): """ Processes the deposit result as presented by sword. We try to set the splash url. We set deposit_status to pending. We do not set a pdf_url because we expect moderation, so a pdf_url would be a dead link (for samoe time). """ try: sword_statement = etree.fromstring(bytes(response, encoding='utf-8')) except etree.XMLSyntaxError: self.log('Invalid XML response from {}'.format(self.repository.name)) raise DepositError(_('The repository {} returned invalid XML').format(self.repository.name)) # We assume one element for the splash url, so we take the first one link_alternate = sword_statement.find("atom:link[@rel='alternate']", namespaces=NSMAP) print(link_alternate) if link_alternate is not None: splash_url = link_alternate.get('href', None) else: splash_url = None if splash_url: identifier = splash_url.split('/')[-1] else: identifier = None msg = "Found no splash url in XML reposonse from repository {}. Either no link[@ref='alternate'] was present or the href was missing.".format(self.repository.name) self.log(msg) logger.warning(msg) # We expect that SWORD Repos usually have moderation. If this is at some point not the case, we can make this more flexible status = 'pending' deposit_result = DepositResult(identifier=identifier, splash_url=splash_url, status=status) return deposit_result
def submit_deposit(self, pdf, form, dry_run=False): conn = None try: self.log("### Connecting") conn = self.get_conn() self.log("### Creating metadata") #entry = self.createMetadata(form) # self.log(entry.pretty_print()) formatter = DCFormatter() meta = formatter.toString(self.paper, 'article.pdf', True, xml_declaration=False) self.log(meta) self.log("### Submitting metadata") #f = StringIO(pdf) # receipt = conn.create(metadata_entry=entry,mimetype="application/pdf", # payload=f,col_iri=self.repository.api_key) #receipt = conn.create(metadata_entry=entry,col_iri=self.repository.api_key) files = {'file': ('metadata.xml', meta)} headers = { 'In-Progress': 'false', 'Content-Type': 'application/atom+xml; type=entry' } auth = requests.auth.HTTPBasicAuth(self.repository.username, self.repository.password) r = requests.post(self.repository.api_key, files=files, headers=headers, auth=auth) self.log_request( r, 201, __('Unable to submit the paper to the collection.')) self.log(unicode(r.text)) deposit_result = DepositResult() except requests.exceptions.RequestException as e: raise DepositError(unicode(e)) except sword2.exceptions.HTTPResponseError as e: if conn is not None: self.log(unicode(conn.history)) raise DepositError(__('Failed to connect to the SWORD server.')) return deposit_result
def submit_deposit(self, pdf, form, dry_run=False): if self.repository.api_key is None: raise DepositError(__("No OSF token provided.")) api_key = self.repository.api_key license_id = form.cleaned_data['license'] deposit_result = DepositResult() # Creating the metadata self.log("### Creating the metadata") min_node_structure, authors, paper_doi, pub_date = ( self.createMetadata(form)) self.log(json.dumps(min_node_structure, indent=4) + '') self.log(json.dumps(authors, indent=4) + '') # Creating a new depository self.log("### Creating a new depository") headers = { 'Authorization': 'Bearer %s' % api_key, 'Content-Type': 'application/vnd.api+json' } osf_response = self.create_node() node_id = osf_response['data']['id'] self.osf_storage_data = get_newnode_osf_storage(node_id) osf_links = self.osf_storage_data['data'] osf_upload_link = str( list({translate_links(entry) for entry in osf_links})) osf_upload_link = osf_upload_link.replace("[u'", '').replace("']", '') # Uploading the PDF 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=headers) self.log_request(primary_file_data, 201, __('Unable to upload the PDF file.')) primary_file_data = primary_file_data.json() # Uncomment pf_path when time to test the preprint upload has come pf_path = primary_file_data['data']['attributes']['path'][1:] add_contributors() create_license() # Create Preprint osf_preprint_response = create_preprint() preprint_id = osf_preprint_response['data']['id'] update_preprint_license() return (deposit_result)
def submit_deposit(self, pdf, form): """ Submit paper to the repository. This is a wrapper for the subclasses and calls some protocol specific functions. It creates the METS container and deposits. :param pdf: Filename to the PDF file to submit :param form: The form returned by get_form and completed by the user :returns: DepositResult object """ # Raise error if login credentials are missing. These are not mandatory in Admin UI, since alternatively an API Key can be used, but not for SWORD if not (self.repository.username and self.repository.password): raise DepositError(_("Username or password not provided for this repository. Please contact the Dissemin team.")) metadata = self._get_xml_metadata(form) dissemin_metadata = self._get_xml_dissemin_metadata(form) mets = self._get_mets(metadata, dissemin_metadata) # Logging Metadata self.log('Metadata looks like:') self.log(mets) zipfile = self._get_mets_container(pdf, mets) # Send request to repository self.log("### Preparing request to repository") auth = (self.repository.username, self.repository.password) headers = { 'Content-Type': 'application/zip', 'Content-Disposition': 'filename=mets.zip', 'Packaging': 'http://purl.org/net/sword/package/METSMODS', } self.log("### Sending request") r = requests.post(self.repository.endpoint, auth=auth, headers=headers, data=zipfile.getvalue(), timeout=20) self.log_request(r, 201, _('Unable to deposit to repository') + self.repository.name) #Deposit was successful self.log("This is what the repository yelled back:") self.log(r.text) deposit_result = self._get_deposit_result(r.text) # Set the license for the deposit result if delivered deposit_result = self._add_license_to_deposit_result(deposit_result, form) # Set the embargo_date for the deposit result if delivered deposit_result = self._add_embargo_date_to_deposit_result(deposit_result, form) return deposit_result
def createMetadata(self, form): # data = {} paper = self.paper.json() authors = paper['authors'] records = paper['records'] # Look for specific subkey def get_key_data(key): #for item in records.values(): for item in records: if item.get(key): # if item.key: return item[key] return None # Abstract # abstract = form.cleaned_data[ # 'abstract'] or kill_html(self.paper.abstract) abstract = get_key_data('abstract') # abstract = records.description # Check that there is an abstract if abstract: self.log('No abstract found, aborting') raise DepositError( __('No abstract is available for this paper but ' + 'OSF Preprints requires to attach one. ' + 'Please use the metadata panel to provide one')) # tags = get_key_data('keywords') # Required to create a new node. # The project will then host the preprint. min_node_structure = { "data": { "type": "nodes", "attributes": { "title": paper['title'], "category": "project", # "description": self.paper.oairecords.description "description": "This text is a simple description to fill this field." # "tags": p_tags.replace('-', '').split(), } } } return min_node_structure, authors
def _get_deposit_result(self, response): """ Processes the deposit result as presented by sword. We try to set the splash url. We set deposit_status to pending. We do not set a pdf_url because we expect moderation, so a pdf_url would be a dead link (for samoe time). """ try: sword_statement = etree.fromstring( bytes(response, encoding='utf-8')) except etree.XMLSyntaxError: self.log('Invalid XML response from {}'.format( self.repository.name)) raise DepositError( _('The repository {} returned invalid XML').format( self.repository.name)) original_deposit = sword_statement.find( './/sword:originalDeposit', namespaces=sword_statement.nsmap) if original_deposit is None: splash_url = None else: splash_url = original_deposit.get('href', None) if splash_url is not None: identifier = splash_url.split('/')[-1] else: identifier = None msg = 'Found no splash url in XML reposonse from repository {}. Either no originalDeposit was present or the href was missing.'.format( self.repository.name) self.log(msg) logger.warning(msg) # We expect that SWORD Repos usually have moderation. If this is at some point not the case, we can make this more flexible status = 'pending' deposit_result = DepositResult(identifier=identifier, splash_url=splash_url, status=status) return deposit_result
def log_request(self, r, expected_status_code, error_msg): """ Logs an HTTP request and raises an error if the status code is unexpected. """ # Call the generic log_request handler to check if there is any error super_exc = None try: super(ZenodoProtocol, self).log_request(r, expected_status_code, error_msg) except DepositError as exc: super_exc = exc # No error (request went as expected), we can just return if super_exc is None: return # If there was an error, do the Zenodo-specific error handling here. try: error = r.json() # Check for validation errors because the DOI already exists if (r.status_code == 400 and 'Validation error' in error.get('message') and any([ 'DOI already exists' in item.get('message') for item in error.get('errors', []) ])): raise DepositError( _('This document is already in Zenodo. ' 'Zenodo refused the deposit.')) except Exception as exc: if isinstance(exc, DepositError): # Any DepositError is simply kept as is raise exc else: # There was an error within error handling code, just return # the super exception raise super_exc
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
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
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
def submit_deposit(self, pdf, form, dry_run=False): if self.repository.api_key is None: raise DepositError(__("No OSF token provided.")) api_key = self.repository.api_key deposit_result = DepositResult() # Creating the metadata self.log("### Creating the metadata") min_node_structure, authors = self.createMetadata(form) self.log(json.dumps(min_node_structure, indent=4) + '') self.log(json.dumps(authors, indent=4) + '') # Get a dictionary containing the first and last names # of the authors of a Dissemin paper, # ready to be implemented in an OSF Preprints data dict. def translate_authors(dissemin_authors): # first_name = dissemin_authors.paper.name.first # last_name = dissemin_authors.paper.name.last first_name = dissemin_authors['name']['first'] last_name = dissemin_authors['name']['last'] structure = { "data": { "type": "contributors", "attributes": { "full_name": "{} {}".format(first_name, last_name) } } } return structure # Extract the OSF Storage link def translate_links(node_links): upload_link = node_links['links']['upload'] return upload_link # 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 OSF.')) # Creating the metadata # self.log("### Creating the metadata") # data = self.createMetadata(form) # self.log(json.dumps(data, indent=4)+'') # Creating a new depository self.log("### Creating a new depository") headers = { 'Authorization': 'Bearer %s' % api_key, 'Content-Type': 'application/vnd.api+json' } # Send the min. structure. # The response should contain the node ID. def create_node(): osf_response = requests.post(self.api_url, data=json.dumps(min_node_structure), headers=headers).json() return osf_response osf_response = create_node() # self.log(osf_response) node_id = osf_response['data']['id'] # Get OSF Storage link # to later upload the Preprint PDF file. def get_newnode_osf_storage(node_id): self.storage_url = self.api_url + "{}/files/".format(node_id) osf_storage_data = requests.get(self.storage_url, headers=headers).json() return osf_storage_data self.osf_storage_data = get_newnode_osf_storage(node_id) osf_links = self.osf_storage_data['data'] osf_upload_link = str( list({translate_links(entry) for entry in osf_links})) osf_upload_link = osf_upload_link.replace("[u'", '').replace("']", '') # Uploading the PDF 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=headers).json() pf_path = primary_file_data['data']['attributes']['path'][1:] # self.log_request(primary_file_data, 201, __( # 'Unable to transfer the document to OSF.')) # Creating the metadata ## self.log("### Creating the metadata") ## data = self.createMetadata(form) ## self.log(json.dumps(data, indent=4)+'') # Add contributors def add_contributors(): contrib_url = self.api_url + node_id + "/contributors/" for author in authors: contrib = translate_authors(author) contrib_response = requests.post(contrib_url, data=json.dumps(contrib), headers=headers).json() add_contributors() # Submitting the metadata self.log("### Submitting the metadata") # r = requests. # r = requests.post(api_url_with_key, data=str("{}"), headers=headers) # self.log_request(r, 201,__( # 'Unable to create a new deposition on OSF Preprints.')) # deposition_id = r.json() return deposit_result
def get_conn(self): if self.repository.endpoint is None: raise DepositError(__("No servicedocument provided.")) return sword2.Connection(self.repository.endpoint, user_name=self.repository.username, user_pass=self.repository.password)
def submit_deposit(self, pdf, form, dry_run=False): if self.repository.api_key is None: raise DepositError(__("No OSF token provided.")) api_key = self.repository.api_key license_id = form.cleaned_data['license'] deposit_result = DepositResult() # Creating the metadata self.log("### Creating the metadata") min_node_structure, authors, paper_doi, pub_date = ( self.createMetadata(form)) self.log(json.dumps(min_node_structure, indent=4) + '') self.log(json.dumps(authors, indent=4) + '') # Get a dictionary containing the first and last names # of the authors of a Dissemin paper, # ready to be implemented in an OSF Preprints data dict. def translate_author(dissemin_authors, goal="optional"): author = "{} {}".format(dissemin_authors['name']['first'], dissemin_authors['name']['last']) if goal == "contrib": structure = { "data": { "type": "contributors", "attributes": { "full_name": author } } } return (structure) else: return (author) # Extract the OSF Storage link def translate_links(node_links): upload_link = node_links['links']['upload'] return (upload_link) # Creating a new depository self.log("### Creating a new depository") headers = { 'Authorization': 'Bearer %s' % api_key, 'Content-Type': 'application/vnd.api+json' } # Send the min. structure. # The response should contain the node ID. def create_node(): osf_response = requests.post(self.api_url, data=json.dumps(min_node_structure), headers=headers) self.log_request(osf_response, 201, __('Unable to create a project on OSF.')) osf_response = osf_response.json() return (osf_response) osf_response = create_node() node_id = osf_response['data']['id'] # Get OSF Storage link # to later upload the Preprint PDF file. def get_newnode_osf_storage(node_id): self.storage_url = self.api_url + "{}/files/".format(node_id) osf_storage_data = requests.get(self.storage_url, headers=headers) self.log_request(osf_storage_data, 200, __('Unable to authenticate to OSF.')) osf_storage_data = osf_storage_data.json() return (osf_storage_data) self.osf_storage_data = get_newnode_osf_storage(node_id) osf_links = self.osf_storage_data['data'] osf_upload_link = str( list({translate_links(entry) for entry in osf_links})) osf_upload_link = osf_upload_link.replace("[u'", '').replace("']", '') # Uploading the PDF 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=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:] # Add contributors def add_contributors(): contrib_url = self.api_url + node_id + "/contributors/" for author in authors: contrib = translate_author(author, "contrib") contrib_response = requests.post(contrib_url, data=json.dumps(contrib), headers=headers) self.log_request(contrib_response, 201, __('Unable to add contributors.')) add_contributors() def create_license(): node_url = self.api_url + node_id + "/" license_url = "https://api.osf.io/v2/licenses/" license_url = license_url + "{}".format(license_id) + "/" authors_list = [translate_author(author) for author in authors] license_structure = { "data": { "type": "nodes", "id": node_id, "attributes": {}, "relationships": { "license": { "data": { "type": "licenses", "id": license_id } } } } } if license_id == NO_LICENSE_ID: license_structure['data']['attributes'] = { "node_license": { "year": pub_date, "copyright_holders": authors_list } } else: license_structure['data']['attributes'] = {"node_license": {}} license_req = requests.patch(node_url, data=json.dumps(license_structure), headers=headers) self.log_request(license_req, 200, __('Unable to update license.')) # license_response = license_req.json() # Updating License self.log("### Updating License") self.log(str(license_req.status_code)) self.log(license_req.text) create_license() def create_preprint(): license_url = "https://api.osf.io/v2/licenses/" license_url = license_url + "{}".format(license_id) min_preprint_structure = { "data": { "attributes": { "doi": paper_doi }, "relationships": { "node": { "data": { "type": "nodes", "id": node_id } }, "primary_file": { "data": { "type": "primary_files", "id": pf_path } }, "license": { "links": { "related": { "href": license_url, "meta": {} } } }, "provider": { "data": { "type": "providers", "id": "osf" } } } } } return (deposit_result)