diff --git a/site/cds_rdm/inspire_harvester/utils.py b/site/cds_rdm/inspire_harvester/utils.py index 47e42e05..0d46acfd 100644 --- a/site/cds_rdm/inspire_harvester/utils.py +++ b/site/cds_rdm/inspire_harvester/utils.py @@ -22,6 +22,21 @@ def retrieve_identifiers(identifiers, scheme): yield ident["identifier"] +def pids_equal(left, right): + """Compare PIDs ignoring DataCite client on the DOI.""" + left, right = dict(left), dict(right) + for pids in (left, right): + doi = pids.get("doi") + if doi: + pids["doi"] = {k: doi[k] for k in ("identifier", "provider") if k in doi} + return left == right + + +def _present_keys(value): + """Keys that have stored content, not empty dump placeholders.""" + return {k for k, v in value.items() if v not in (None, [], {})} + + def compare_metadata(a, b): """Compare metadata based on id key only.""" # If both are dicts @@ -30,11 +45,13 @@ def compare_metadata(a, b): if "id" in a and "id" in b: return a["id"] == b["id"] + keys_a, keys_b = _present_keys(a), _present_keys(b) + # Otherwise compare keys recursively - if a.keys() != b.keys(): + if keys_a != keys_b: return False - return all(compare_metadata(a[k], b[k]) for k in a) + return all(compare_metadata(a[k], b[k]) for k in keys_a) # If both are lists if isinstance(a, list) and isinstance(b, list): @@ -42,6 +59,9 @@ def compare_metadata(a, b): return False return all(compare_metadata(x, y) for x, y in zip(a, b)) + if isinstance(a, str) and isinstance(b, str): + return a.casefold() == b.casefold() + # Fallback normal comparison return a == b diff --git a/site/cds_rdm/inspire_harvester/writer.py b/site/cds_rdm/inspire_harvester/writer.py index 5ae39a91..e0ab9e7b 100644 --- a/site/cds_rdm/inspire_harvester/writer.py +++ b/site/cds_rdm/inspire_harvester/writer.py @@ -36,7 +36,7 @@ UpdateEngine, UpdateEngineConflict, ) -from cds_rdm.inspire_harvester.utils import compare_metadata +from cds_rdm.inspire_harvester.utils import compare_metadata, pids_equal from cds_rdm.utils import compact_text @@ -178,7 +178,7 @@ def _update_record( if should_update_files and has_cds_doi and latest_res_type_changed: self._resource_type_versioning(record, update_metadata, ctx, logger) else: - is_pids_equal = update_metadata["pids"] == record_dict["pids"] + is_pids_equal = pids_equal(update_metadata["pids"], record_dict["pids"]) is_metadata_equal = compare_metadata( update_metadata["metadata"], record_dict["metadata"] )