Example #1
0
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)
Example #4
0
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
Example #8
0
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")
Example #9
0
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
Example #10
0
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")
Example #11
0
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")
Example #12
0
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
Example #13
0
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
Example #14
0
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)
Example #15
0
    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)
Example #16
0
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
Example #17
0
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.
    """
Example #19
0
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)
Example #22
0
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)