import hashlib
import logging
from lakesuperior import env
from lakesuperior.exceptions import (
ChecksumValidationError, IncompatibleLdpTypeError)
from lakesuperior.migrator import Migrator
__doc__ = """
Admin API.
This module contains maintenance utilities and stats.
"""
logger = logging.getLogger(__name__)
[docs]def stats():
"""
Get repository statistics.
:rtype: dict
:return: Store statistics, resource statistics.
"""
env.setup()
with env.app_globals.rdf_store.txn_ctx():
repo_stats = {
'rsrc_stats': env.app_globals.rdfly.count_rsrc(),
'store_stats': env.app_globals.rdf_store.stats(),
'nonrdf_stats': {
'ct': env.app_globals.nonrdfly.file_ct,
'size': env.app_globals.nonrdfly.store_size,
},
}
return repo_stats
[docs]def migrate(src, dest, start_pts=None, list_file=None, **kwargs):
"""
Migrate an LDP repository to a new Lakesuperior instance.
See :py:meth:`Migrator.__init__`.
"""
if start_pts:
if not isinstance(
start_pts, list) and not isinstance(start_pts, tuple):
start_pts = (start_pts,)
elif not list_file:
start_pts = ('/',)
return Migrator(src, dest, **kwargs).migrate(start_pts, list_file)
[docs]def integrity_check():
"""
Check integrity of the data set.
At the moment this is limited to referential integrity. Other checks can
be added and triggered by different argument flags.
"""
env.setup()
with env.app_globals.rdfly.store.txn_ctx():
return set(env.app_globals.rdfly.find_refint_violations())
[docs]def fixity_check(uid):
"""
Check fixity of a resource.
This calculates the checksum of a resource and validates it against the
checksum stored in its metadata (``premis:hasMessageDigest``).
:param str uid: UID of the resource to be checked.
:rtype: None
:raises: lakesuperior.exceptions.ChecksumValidationError: the cecksums
do not match. This indicates corruption.
:raises: lakesuperior.exceptions.IncompatibleLdpTypeError: if the
resource is not an LDP-NR.
"""
env.setup()
from lakesuperior.api import resource as rsrc_api
from lakesuperior.dictionaries.namespaces import ns_collection as nsc
from lakesuperior.model.ldp.ldp_factory import LDP_NR_TYPE
rsrc = rsrc_api.get(uid)
with env.app_globals.rdf_store.txn_ctx():
if LDP_NR_TYPE not in rsrc.ldp_types:
raise IncompatibleLdpTypeError()
ref_digest_term = rsrc.metadata.value(nsc['premis'].hasMessageDigest)
ref_digest_parts = ref_digest_term.split(':')
ref_cksum = ref_digest_parts[-1]
ref_cksum_algo = ref_digest_parts[-2]
calc_cksum = hashlib.new(ref_cksum_algo, rsrc.content.read()).hexdigest()
if calc_cksum != ref_cksum:
raise ChecksumValidationError(uid, ref_cksum, calc_cksum)
logger.info(f'Fixity check passed for {uid}.')