def oai_error(argd, errors): """ Return a well-formatted OAI-PMH error """ out = """<?xml version="1.0" encoding="UTF-8"?> <OAI-PMH xmlns="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">""" out += X.responseDate()(get_utc_now()) for error_code, error_msg in errors: assert (error_code in CFG_ERRORS) if error_code in ("badArgument", "badVerb"): out += X.request()(oai_get_request_url()) break else: ## There are no badArgument or badVerb errors so we can ## return the whole request information out += X.request(**argd)(oai_get_request_url()) for error_code, error_msg in errors: if error_msg is None: error_msg = CFG_ERRORS[error_code] else: error_msg = "%s %s" % (CFG_ERRORS[error_code], error_msg) out += X.error(code=error_code)(error_msg) out += "</OAI-PMH>" return out
def oai_error(argd, errors): """ Return a well-formatted OAI-PMH error """ out = """<?xml version="1.0" encoding="UTF-8"?> <OAI-PMH xmlns="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">""" out += X.responseDate()(get_utc_now()) for error_code, error_msg in errors: assert(error_code in CFG_ERRORS) if error_code in ("badArgument", "badVerb"): out += X.request()(oai_get_request_url()) break else: ## There are no badArgument or badVerb errors so we can ## return the whole request information out += X.request(**argd)(oai_get_request_url()) for error_code, error_msg in errors: if error_msg is None: error_msg = CFG_ERRORS[error_code] else: error_msg = "%s %s" % (CFG_ERRORS[error_code], error_msg) out += X.error(code=error_code)(error_msg) out += "</OAI-PMH>" return out
def oai_build_request_element(argd=None): """ Build the request tag. """ if argd is None: argd = {} return X.responseDate()(get_utc_now()) + X.request(**argd)("%s/oai2d" % CFG_SITE_SECURE_URL or CFG_SITE_URL)
def oai_build_request_element(argd=None): """ Build the request tag. """ if argd is None: argd = {} return X.responseDate()(get_utc_now()) + X.request(**argd)( "%s/oai2d" % CFG_SITE_URL)
def oai_list_records_or_identifiers(req, argd): """Generates response to oai_list_records verb.""" verb = argd['verb'] resumption_token_was_specified = False # check if the resumption_token did not expire if argd.get('resumptionToken'): resumption_token_was_specified = True try: cache = oai_cache_load(argd['resumptionToken']) last_recid = cache['last_recid'] argd = cache['argd'] complete_list = cache['complete_list'] complete_list = filter_out_based_on_date_range(complete_list, argd.get('from', ''), argd.get('until', '')) except Exception: register_exception(alert_admin=True) req.write(oai_error(argd, [("badResumptionToken", "ResumptionToken expired or invalid: %s" % argd['resumptionToken'])])) return else: last_recid = 0 complete_list = oai_get_recid_list(argd.get('set', ""), argd.get('from', ""), argd.get('until', "")) if not complete_list: # noRecordsMatch error req.write(oai_error(argd, [("noRecordsMatch", "no records correspond to the request")])) return cursor = 0 for cursor, recid in enumerate(complete_list): ## Let's fast-forward the cursor to point after the last recid that was ## disseminated successfully if recid > last_recid: break set_last_updated = get_set_last_update(argd.get('set', "")) req.write(oai_header(argd, verb)) for recid in list(complete_list)[cursor:cursor+CFG_OAI_LOAD]: req.write(print_record(recid, argd['metadataPrefix'], verb=verb, set_spec=argd.get('set'), set_last_updated=set_last_updated)) if list(complete_list)[cursor+CFG_OAI_LOAD:]: resumption_token = oai_generate_resumption_token(argd.get('set', '')) cache = { 'argd': argd, 'last_recid': recid, 'complete_list': complete_list.fastdump(), } oai_cache_dump(resumption_token, cache) expdate = oai_get_response_date(CFG_OAI_EXPIRE) req.write(X.resumptionToken(expirationDate=expdate, cursor=cursor, completeListSize=len(complete_list))(resumption_token)) elif resumption_token_was_specified: ## Since a resumptionToken was used we shall put a last empty resumptionToken req.write(X.resumptionToken(cursor=cursor, completeListSize=len(complete_list))("")) req.write(oai_footer(verb)) oai_cache_gc()
def oai_list_metadata_formats(argd): """Generates response to oai_list_metadata_formats verb.""" if argd.get('identifier'): recid = oai_get_recid(argd['identifier']) _record_exists = record_exists(recid) if _record_exists != 1 and (_record_exists != -1 or CFG_OAI_DELETED_POLICY == "no"): return oai_error(argd, [("idDoesNotExist", "invalid record Identifier: %s" % argd['identifier'])]) out = "" for prefix, (dummy, schema, namespace) in CFG_OAI_METADATA_FORMATS.items(): out += X.metadataFormat()( X.metadataPrefix(prefix), X.schema(schema), X.metadataNamespace(namespace) ) return oai_header(argd, "ListMetadataFormats") + out + oai_footer("ListMetadataFormats")
def oai_header(argd, verb): """ Return OAI header """ out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "\n" out += "<?xml-stylesheet type=\"text/xsl\" href=\"%s/css/oai2.xsl.v1.0\" ?>\n" % CFG_SITE_SECURE_URL or CFG_SITE_URL out += "<OAI-PMH xmlns=\"http://www.openarchives.org/OAI/2.0/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd\">\n" #out += "<responseDate>%s</responseDate>" % get_utc_now() out += X.responseDate()(get_utc_now()) if verb: out += X.request(**argd)(oai_get_request_url()) out += "<%s>\n" % verb else: out += X.request()(oai_get_request_url()) return out
def oai_list_metadata_formats(argd): """Generates response to oai_list_metadata_formats verb.""" if argd.get('identifier'): recid = oai_get_recid(argd['identifier']) _record_exists = record_exists(recid) if _record_exists != 1 and (_record_exists != -1 or CFG_OAI_DELETED_POLICY == "no"): return oai_error( argd, [("idDoesNotExist", "invalid record Identifier: %s" % argd['identifier'])]) out = "" for prefix, (dummy, schema, namespace) in CFG_OAI_METADATA_FORMATS.items(): out += X.metadataFormat()(X.metadataPrefix(prefix), X.schema(schema), X.metadataNamespace(namespace)) return oai_header( argd, "ListMetadataFormats") + out + oai_footer("ListMetadataFormats")
def oai_header(argd, verb): """ Return OAI header """ out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "\n" out += "<?xml-stylesheet type=\"text/xsl\" href=\"%s/css/oai2.xsl.v1.0\" ?>\n" % CFG_SITE_URL out += "<OAI-PMH xmlns=\"http://www.openarchives.org/OAI/2.0/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd\">\n" #out += "<responseDate>%s</responseDate>" % get_utc_now() out += X.responseDate()(get_utc_now()) if verb: out += X.request(**argd)(oai_get_request_url()) out += "<%s>\n" % verb else: out += X.request()(oai_get_request_url()) return out
def oai_list_sets(argd): """ Lists available sets for OAI metadata harvesting. """ out = "" # note: no flow control in ListSets sets = get_all_sets().values() if not sets: return oai_error(argd, [("noSetHierarchy", "No sets have been configured for this repository")]) for set_ in sets: out += " <set>\n" out += X.setSpec()(set_[0]) + X.setName()(set_[1]) if set_[2]: out += X.setDescription()(set_[2]) out = out + " </set>\n" return oai_header(argd, "ListSets") + out + oai_footer("ListSets")
def oai_list_sets(argd): """ Lists available sets for OAI metadata harvesting. """ out = "" # note: no flow control in ListSets sets = get_all_sets().values() if not sets: return oai_error( argd, [("noSetHierarchy", "No sets have been configured for this repository")]) for set_ in sets: out += " <set>\n" out += X.setSpec()(set_[0]) + X.setName()(set_[1]) if set_[2]: out += X.setDescription()(set_[2]) out = out + " </set>\n" return oai_header(argd, "ListSets") + out + oai_footer("ListSets")
def get_record_provenance(recid): """ Return the provenance XML representation of a record, suitable to be put in the about tag. """ record = get_record(recid) provenances = record_get_field_instances( record, CFG_BIBUPLOAD_EXTERNAL_OAIID_TAG[:3], CFG_BIBUPLOAD_EXTERNAL_OAIID_TAG[3], CFG_BIBUPLOAD_EXTERNAL_OAIID_TAG[4]) out = "" for provenance in provenances: base_url = identifier = datestamp = metadata_namespace = origin_description = harvest_date = altered = "" for (code, value) in provenance[0]: if code == CFG_OAI_PROVENANCE_BASEURL_SUBFIELD: base_url = value elif code == CFG_BIBUPLOAD_EXTERNAL_OAIID_TAG[5]: identifier = value elif code == CFG_OAI_PROVENANCE_DATESTAMP_SUBFIELD: datestamp = value elif code == CFG_OAI_PROVENANCE_METADATANAMESPACE_SUBFIELD: metadata_namespace = value elif code == CFG_OAI_PROVENANCE_ORIGINDESCRIPTION_SUBFIELD: origin_description = value elif code == CFG_OAI_PROVENANCE_HARVESTDATE_SUBFIELD: harvest_date = value elif code == CFG_OAI_PROVENANCE_ALTERED_SUBFIELD: altered = value if base_url: out += """<provenance xmlns="http://www.openarchives.org/OAI/2.0/provenance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/provenance http://www.openarchives.org/OAI/2.0/provenance.xsd">""" out += X.originDescription( harvestDate=harvest_date, altered=altered)( X.baseURL()(base_url), X.identifier()(identifier), X.datestamp()(datestamp), X.metadataNamespace()(metadata_namespace), origin_description and X.originDescription(origin_description) or '' ## This is already XML ) out += """</provenance>""" return out
def get_record_provenance(recid): """ Return the provenance XML representation of a record, suitable to be put in the about tag. """ record = get_record(recid) provenances = record_get_field_instances(record, CFG_BIBUPLOAD_EXTERNAL_OAIID_TAG[:3], CFG_BIBUPLOAD_EXTERNAL_OAIID_TAG[3], CFG_BIBUPLOAD_EXTERNAL_OAIID_TAG[4]) out = "" for provenance in provenances: base_url = identifier = datestamp = metadata_namespace = origin_description = harvest_date = altered = "" for (code, value) in provenance[0]: if code == CFG_OAI_PROVENANCE_BASEURL_SUBFIELD: base_url = value elif code == CFG_BIBUPLOAD_EXTERNAL_OAIID_TAG[5]: identifier = value elif code == CFG_OAI_PROVENANCE_DATESTAMP_SUBFIELD: datestamp = value elif code == CFG_OAI_PROVENANCE_METADATANAMESPACE_SUBFIELD: metadata_namespace = value elif code == CFG_OAI_PROVENANCE_ORIGINDESCRIPTION_SUBFIELD: origin_description = value elif code == CFG_OAI_PROVENANCE_HARVESTDATE_SUBFIELD: harvest_date = value elif code == CFG_OAI_PROVENANCE_ALTERED_SUBFIELD: altered = value if base_url: out += """<provenance xmlns="http://www.openarchives.org/OAI/2.0/provenance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/provenance http://www.openarchives.org/OAI/2.0/provenance.xsd">""" out += X.originDescription(harvestDate=harvest_date, altered=altered)( X.baseURL()(base_url), X.identifier()(identifier), X.datestamp()(datestamp), X.metadataNamespace()(metadata_namespace), origin_description and X.originDescription(origin_description) or '' ## This is already XML ) out += """</provenance>""" return out
def print_record(recid, prefix='marcxml', verb='ListRecords', set_spec=None, set_last_updated=None): """Prints record 'recid' formatted according to 'prefix'. - if record does not exist, return nothing. - if record has been deleted and CFG_OAI_DELETED_POLICY is 'transient' or 'deleted', then return only header, with status 'deleted'. - if record has been deleted and CFG_OAI_DELETED_POLICY is 'no', then return nothing. """ record_exists_result = record_exists(recid) == 1 if record_exists_result: sets = get_field(recid, CFG_OAI_SET_FIELD) if set_spec is not None and not set_spec in sets and not [set_ for set_ in sets if set_.startswith("%s:" % set_spec)]: ## the record is not in the requested set, and is not ## in any subset record_exists_result = False if record_exists_result: status = None else: status = 'deleted' if not record_exists_result and CFG_OAI_DELETED_POLICY not in ('persistent', 'transient'): return "" idents = get_field(recid, CFG_OAI_ID_FIELD) if not idents: return "" ## FIXME: Move these checks in a bibtask #try: #assert idents, "No OAI ID for record %s, please do your checks!" % recid #except AssertionError, err: #register_exception(alert_admin=True) #return "" #try: #assert len(idents) == 1, "More than OAI ID found for recid %s. Considering only the first one, but please do your checks: %s" % (recid, idents) #except AssertionError, err: #register_exception(alert_admin=True) ident = idents[0] header_body = EscapedXMLString('') header_body += X.identifier()(ident) if set_last_updated: header_body += X.datestamp()(max(get_modification_date(recid), set_last_updated)) else: header_body += X.datestamp()(get_modification_date(recid)) for set_spec in get_field(recid, CFG_OAI_SET_FIELD): if set_spec and set_spec != CFG_OAI_REPOSITORY_GLOBAL_SET_SPEC: # Print only if field not empty header_body += X.setSpec()(set_spec) header = X.header(status=status)(header_body) if verb == 'ListIdentifiers': return header else: if record_exists_result: metadata_body = format_record(recid, CFG_OAI_METADATA_FORMATS[prefix][0]) metadata = X.metadata(body=metadata_body) provenance_body = get_record_provenance(recid) if provenance_body: provenance = X.about(body=provenance_body) else: provenance = '' rights_body = get_record_rights(recid) if rights_body: rights = X.about(body=rights_body) else: rights = '' else: metadata = '' provenance = '' rights = '' return X.record()(header, metadata, provenance, rights)
try: assert idents, "No OAI ID for record %s, please do your checks!" % recid except AssertionError, err: register_exception(alert_admin=True) return try: assert len( idents ) == 1, "More than OAI ID found for recid %s. Considering only the first one, but please do your checks: %s" % ( recid, idents) except AssertionError, err: register_exception(alert_admin=True) ident = idents[0] header_body = EscapedXMLString('') header_body += X.identifier()(ident) header_body += X.datestamp()(get_modification_date(recid)) for set_spec in get_field(recid, CFG_OAI_SET_FIELD): if set_spec and set_spec != CFG_OAI_REPOSITORY_GLOBAL_SET_SPEC: # Print only if field not empty header_body += X.setSpec()(set_spec) header = X.header(status=status)(header_body) if verb == 'ListIdentifiers': return header else: if record_exists_result: metadata_body = format_record(recid, CFG_OAI_METADATA_FORMATS[prefix][0]) metadata = X.metadata(body=metadata_body)
def oai_identify(argd): """Generates a response to oai_identify verb. script_url - *str* URL of the script used to access the service. This is made necessary since the gateway can be accessed either via /oai2d or /oai2d/ (or for backward compatibility: oai2d.py or oai2d.py/), and that the base URL must be returned in the Identify response """ out = X.repositoryName()(CFG_SITE_NAME) out += X.baseURL()(CFG_SITE_URL + '/oai2d') out += X.protocolVersion()("2.0") out += X.adminEmail()(CFG_SITE_SUPPORT_EMAIL) out += X.earliestDatestamp()(get_earliest_datestamp()) out += X.deletedRecord()(CFG_OAI_DELETED_POLICY) out += X.granularity()("YYYY-MM-DDThh:mm:ssZ") if CFG_WEBSTYLE_HTTP_USE_COMPRESSION: out += X.compression()('deflate') out += X.description( """<oai-identifier xmlns="http://www.openarchives.org/OAI/2.0/oai-identifier" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai-identifier http://www.openarchives.org/OAI/2.0/oai-identifier.xsd">""" + X.scheme()("oai") + X.repositoryIdentifier()(CFG_OAI_ID_PREFIX) + X.delimiter()(":") + X.sampleIdentifier()(CFG_OAI_SAMPLE_IDENTIFIER) + """</oai-identifier>""") out += CFG_OAI_IDENTIFY_DESCRIPTION if CFG_OAI_FRIENDS: friends = """<friends xmlns="http://www.openarchives.org/OAI/2.0/friends/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/friends/ http://www.openarchives.org/OAI/2.0/friends.xsd">""" for baseurl in CFG_OAI_FRIENDS: friends += X.baseURL()(baseurl) friends += """</friends>""" out += X.description(friends) out = oai_header(argd, "Identify") + out + oai_footer("Identify") return out
def oai_list_records_or_identifiers(req, argd): """Generates response to oai_list_records verb.""" verb = argd['verb'] resumption_token_was_specified = False # check if the resumption_token did not expire if argd.get('resumptionToken'): resumption_token_was_specified = True try: cache = oai_cache_load(argd['resumptionToken']) last_recid = cache['last_recid'] argd = cache['argd'] complete_list = cache['complete_list'] complete_list = filter_out_based_on_date_range( complete_list, argd.get('from', ''), argd.get('until', '')) except Exception: register_exception(alert_admin=True) req.write( oai_error(argd, [("badResumptionToken", "ResumptionToken expired or invalid: %s" % argd['resumptionToken'])])) return else: last_recid = 0 complete_list = oai_get_recid_list(argd.get('set', ""), argd.get('from', ""), argd.get('until', "")) if not complete_list: # noRecordsMatch error req.write( oai_error(argd, [ ("noRecordsMatch", "no records correspond to the request") ])) return cursor = 0 for cursor, recid in enumerate(complete_list): ## Let's fast-forward the cursor to point after the last recid that was ## disseminated successfully if recid > last_recid: break req.write(oai_header(argd, verb)) for recid in list(complete_list)[cursor:cursor + CFG_OAI_LOAD]: req.write( print_record(recid, argd['metadataPrefix'], verb=verb, set_spec=argd.get('set'))) if list(complete_list)[cursor + CFG_OAI_LOAD:]: resumption_token = oai_generate_resumption_token(argd.get('set', '')) cache = { 'argd': argd, 'last_recid': recid, 'complete_list': complete_list.fastdump(), } oai_cache_dump(resumption_token, cache) expdate = oai_get_response_date(CFG_OAI_EXPIRE) req.write( X.resumptionToken( expirationDate=expdate, cursor=cursor, completeListSize=len(complete_list))(resumption_token)) elif resumption_token_was_specified: ## Since a resumptionToken was used we shall put a last empty resumptionToken req.write( X.resumptionToken(cursor=cursor, completeListSize=len(complete_list))("")) req.write(oai_footer(verb)) oai_cache_gc()
verb=verb, set_spec=argd.get('set'), set_last_updated=set_last_updated)) if list(complete_list)[cursor + CFG_OAI_LOAD:]: resumption_token = oai_generate_resumption_token(argd.get('set', '')) cache = { 'argd': argd, 'last_recid': recid, 'complete_list': complete_list.fastdump(), } oai_cache_dump(resumption_token, cache) expdate = oai_get_response_date(CFG_OAI_EXPIRE) req.write( X.resumptionToken( expirationDate=expdate, cursor=cursor, completeListSize=len(complete_list))(resumption_token)) elif resumption_token_was_specified: ## Since a resumptionToken was used we shall put a last empty resumptionToken req.write( X.resumptionToken(cursor=cursor, completeListSize=len(complete_list))("")) req.write(oai_footer(verb)) oai_cache_gc() def oai_list_sets(argd): """ Lists available sets for OAI metadata harvesting. """
def oai_identify(argd): """Generates a response to oai_identify verb. script_url - *str* URL of the script used to access the service. This is made necessary since the gateway can be accessed either via /oai2d or /oai2d/ (or for backward compatibility: oai2d.py or oai2d.py/), and that the base URL must be returned in the Identify response """ out = X.repositoryName()(CFG_SITE_NAME) out += X.baseURL()((CFG_SITE_SECURE_URL or CFG_SITE_URL) + '/oai2d') out += X.protocolVersion()("2.0") out += X.adminEmail()(CFG_SITE_SUPPORT_EMAIL) out += X.earliestDatestamp()(get_earliest_datestamp()) out += X.deletedRecord()(CFG_OAI_DELETED_POLICY) out += X.granularity()("YYYY-MM-DDThh:mm:ssZ") if CFG_WEBSTYLE_HTTP_USE_COMPRESSION: out += X.compression()('deflate') out += X.description("""<oai-identifier xmlns="http://www.openarchives.org/OAI/2.0/oai-identifier" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai-identifier http://www.openarchives.org/OAI/2.0/oai-identifier.xsd">""" + X.scheme()("oai") + X.repositoryIdentifier()(CFG_OAI_ID_PREFIX) + X.delimiter()(":") + X.sampleIdentifier()(CFG_OAI_SAMPLE_IDENTIFIER) + """</oai-identifier>""") out += CFG_OAI_IDENTIFY_DESCRIPTION % {'CFG_SITE_URL': EscapedXMLString(CFG_SITE_SECURE_URL or CFG_SITE_URL)} if CFG_OAI_FRIENDS: friends = """<friends xmlns="http://www.openarchives.org/OAI/2.0/friends/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/friends/ http://www.openarchives.org/OAI/2.0/friends.xsd">""" for baseurl in CFG_OAI_FRIENDS: friends += X.baseURL()(baseurl) friends += """</friends>""" out += X.description(friends) out = oai_header(argd, "Identify") + out + oai_footer("Identify") return out
set_last_updated = get_set_last_update(argd.get('set', "")) req.write(oai_header(argd, verb)) for recid in list(complete_list)[cursor:cursor+CFG_OAI_LOAD]: req.write(print_record(recid, argd['metadataPrefix'], verb=verb, set_spec=argd.get('set'), set_last_updated=set_last_updated)) if list(complete_list)[cursor+CFG_OAI_LOAD:]: resumption_token = oai_generate_resumption_token(argd.get('set', '')) cache = { 'argd': argd, 'last_recid': recid, 'complete_list': complete_list.fastdump(), } oai_cache_dump(resumption_token, cache) expdate = oai_get_response_date(CFG_OAI_EXPIRE) req.write(X.resumptionToken(expirationDate=expdate, cursor=cursor, completeListSize=len(complete_list))(resumption_token)) elif resumption_token_was_specified: ## Since a resumptionToken was used we shall put a last empty resumptionToken req.write(X.resumptionToken(cursor=cursor, completeListSize=len(complete_list))("")) req.write(oai_footer(verb)) oai_cache_gc() def oai_list_sets(argd): """ Lists available sets for OAI metadata harvesting. """ out = "" # note: no flow control in ListSets sets = get_all_sets().values()
return idents = get_field(recid, CFG_OAI_ID_FIELD) try: assert idents, "No OAI ID for record %s, please do your checks!" % recid except AssertionError, err: register_exception(alert_admin=True) return try: assert len(idents) == 1, "More than OAI ID found for recid %s. Considering only the first one, but please do your checks: %s" % (recid, idents) except AssertionError, err: register_exception(alert_admin=True) ident = idents[0] header_body = EscapedXMLString('') header_body += X.identifier()(ident) header_body += X.datestamp()(get_modification_date(recid)) for set_spec in get_field(recid, CFG_OAI_SET_FIELD): if set_spec and set_spec != CFG_OAI_REPOSITORY_GLOBAL_SET_SPEC: # Print only if field not empty header_body += X.setSpec()(set_spec) header = X.header(status=status)(header_body) if verb == 'ListIdentifiers': return header else: if record_exists_result: metadata_body = format_record(recid, CFG_OAI_METADATA_FORMATS[prefix][0]) metadata = X.metadata(body=metadata_body) provenance_body = get_record_provenance(recid)
def print_record(recid, prefix='marcxml', verb='ListRecords', set_spec=None, set_last_updated=None): """Prints record 'recid' formatted according to 'prefix'. - if record does not exist, return nothing. - if record has been deleted and CFG_OAI_DELETED_POLICY is 'transient' or 'deleted', then return only header, with status 'deleted'. - if record has been deleted and CFG_OAI_DELETED_POLICY is 'no', then return nothing. """ record_exists_result = record_exists(recid) == 1 if record_exists_result: sets = get_field(recid, CFG_OAI_SET_FIELD) if set_spec is not None and not set_spec in sets and not [ set_ for set_ in sets if set_.startswith("%s:" % set_spec) ]: ## the record is not in the requested set, and is not ## in any subset record_exists_result = False if record_exists_result: status = None else: status = 'deleted' if not record_exists_result and CFG_OAI_DELETED_POLICY not in ( 'persistent', 'transient'): return "" idents = get_field(recid, CFG_OAI_ID_FIELD) if not idents: return "" ## FIXME: Move these checks in a bibtask #try: #assert idents, "No OAI ID for record %s, please do your checks!" % recid #except AssertionError, err: #register_exception(alert_admin=True) #return "" #try: #assert len(idents) == 1, "More than OAI ID found for recid %s. Considering only the first one, but please do your checks: %s" % (recid, idents) #except AssertionError, err: #register_exception(alert_admin=True) ident = idents[0] header_body = EscapedXMLString('') header_body += X.identifier()(ident) if set_last_updated: header_body += X.datestamp()(max(get_modification_date(recid), set_last_updated)) else: header_body += X.datestamp()(get_modification_date(recid)) for set_spec in get_field(recid, CFG_OAI_SET_FIELD): if set_spec and set_spec != CFG_OAI_REPOSITORY_GLOBAL_SET_SPEC: # Print only if field not empty header_body += X.setSpec()(set_spec) header = X.header(status=status)(header_body) if verb == 'ListIdentifiers': return header else: if record_exists_result: metadata_body = format_record(recid, CFG_OAI_METADATA_FORMATS[prefix][0]) metadata = X.metadata(body=metadata_body) provenance_body = get_record_provenance(recid) if provenance_body: provenance = X.about(body=provenance_body) else: provenance = '' rights_body = get_record_rights(recid) if rights_body: rights = X.about(body=rights_body) else: rights = '' else: metadata = '' provenance = '' rights = '' return X.record()(header, metadata, provenance, rights)