@@ -41,13 +41,18 @@ def build_doi(self, preprint):
4141 prefix = preprint .provider .doi_prefix
4242 return settings .DOI_FORMAT .format (prefix = prefix , guid = preprint ._id )
4343
44- def build_metadata (self , preprint , include_relation = True ):
44+ def build_unversioned_doi (self , preprint ):
45+ prefix = preprint .provider .doi_prefix
46+ return settings .DOI_FORMAT .format (prefix = prefix , guid = preprint .get_guid ()._id )
47+
48+ def build_metadata (self , preprint , include_relation = True , include_unversioned_doi = False ):
4549 """Return the crossref metadata XML document for a given preprint as a string for DOI minting purposes
4650
4751 :param preprint: the preprint, or list of preprints to build metadata for
4852 """
4953 if isinstance (preprint , (list , QuerySet )):
5054 preprints = preprint
55+ include_unversioned_doi = False # not supported for bulk batches
5156 else :
5257 preprints = [preprint ]
5358
@@ -74,6 +79,9 @@ def build_metadata(self, preprint, include_relation=True):
7479 for preprint in preprints :
7580 body .append (self .build_posted_content (preprint , element , include_relation ))
7681
82+ if include_unversioned_doi :
83+ body .append (self .build_unversioned_posted_content (preprints [0 ], element ))
84+
7785 root = element .doi_batch (
7886 head ,
7987 body ,
@@ -82,10 +90,12 @@ def build_metadata(self, preprint, include_relation=True):
8290 root .attrib ['{%s}schemaLocation' % XSI ] = CROSSREF_SCHEMA_LOCATION
8391 return lxml .etree .tostring (root )
8492
85- def build_posted_content (self , preprint , element , include_relation ):
93+ def build_posted_content (self , preprint , element , include_relation , doi_override = None , resource_override = None ):
8694 """Build the <posted_content> element for a single preprint
8795 preprint - preprint to build posted_content for
8896 element - namespace element to use when building parts of the XML structure
97+ doi_override - if provided, use this DOI value instead of the preprint's own DOI
98+ resource_override - if provided, use this URL as the <resource> instead of the default
8999 """
90100 from osf .models import SpamStatus
91101
@@ -157,15 +167,27 @@ def build_posted_content(self, preprint, element, include_relation):
157167 posted_content .append (relations_program )
158168
159169 minted_doi = preprint .get_identifier_value ('doi' )
160- doi = minted_doi or self .build_doi (preprint )
170+ doi = doi_override or minted_doi or self .build_doi (preprint )
171+ resource_url = resource_override if resource_override is not None else settings .DOMAIN + preprint ._id
161172 doi_data = [
162173 element .doi (doi ),
163- element .resource (settings . DOMAIN + preprint . _id )
174+ element .resource (resource_url )
164175 ]
165176 posted_content .append (element .doi_data (* doi_data ))
166177
167178 return posted_content
168179
180+ def build_unversioned_posted_content (self , preprint , element ):
181+ latest = preprint .get_guid ().referent
182+ base_guid = latest .get_guid ()._id
183+ return self .build_posted_content (
184+ latest ,
185+ element ,
186+ include_relation = False ,
187+ doi_override = self .build_unversioned_doi (latest ),
188+ resource_override = settings .DOMAIN + base_guid ,
189+ )
190+
169191 def _process_crossref_name (self , contributor ):
170192 # Adapted from logic used in `api/citations/utils.py`
171193 # If the user has a family and given name, use those
@@ -249,7 +271,7 @@ def _build_url(self, **query):
249271
250272 def create_identifier (self , preprint , category , include_relation = True ):
251273 if category == 'doi' :
252- metadata = self .build_metadata (preprint , include_relation )
274+ metadata = self .build_metadata (preprint , include_relation , include_unversioned_doi = True )
253275 doi = self .build_doi (preprint )
254276 username , password = self .get_credentials ()
255277 logger .info (f'Sending metadata for DOI { doi } :\n { metadata } ' )
0 commit comments