From 4d4ca621a5874383e4c757847c4dd3e2fca8746f Mon Sep 17 00:00:00 2001
From: Maximilian Moser <maximilian.moser@tuwien.ac.at>
Date: Wed, 3 Mar 2021 18:19:24 +0100
Subject: [PATCH] Update methods for performing record metadata updates
* per default, try the more modern approach of updating the draft that
is associated with the record's recid (service.update_draft() followed
by service.publish()), and only in case of error fall back to
service.update()
* add a "direct" variant of updating metadata, which circumvents the
record service and directly modifies the record's metadata
* this is not recommended, but can come in handy when more direct access
is required than the record service allows
---
invenio_utilities_tuw/cli/records.py | 35 ++++++++++++++++++++++++++--
1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/invenio_utilities_tuw/cli/records.py b/invenio_utilities_tuw/cli/records.py
index d656d59..0363e27 100644
--- a/invenio_utilities_tuw/cli/records.py
+++ b/invenio_utilities_tuw/cli/records.py
@@ -13,6 +13,8 @@ import sys
import click
from flask.cli import with_appcontext
+from invenio_accounts import current_accounts
+from invenio_db import db
from invenio_files_rest.models import ObjectVersion
from ..utils import get_record_file_service, get_record_service
@@ -99,9 +101,19 @@ def show_record(pid, pid_type, user, pretty_print, raw):
"(default: replace)"
),
)
+@click.option(
+ "--direct",
+ "-d",
+ default=False,
+ is_flag=True,
+ help=(
+ "circumvent the record service, and thus permission checks, "
+ "and update the record directly (not recommended)"
+ )
+)
@option_owners
@with_appcontext
-def update_record(metadata_file, pid, pid_type, user, patch, owners):
+def update_record(metadata_file, pid, pid_type, user, patch, owners, direct):
"""Update the specified draft's metadata."""
pid = convert_to_recid(pid, pid_type)
identity = get_identity_for_user(user)
@@ -117,7 +129,26 @@ def update_record(metadata_file, pid, pid_type, user, patch, owners):
metadata = set_record_owners(metadata, owners)
metadata = set_creatibutor_names(metadata)
- service.update(id_=pid, identity=identity, data=metadata)
+ if direct:
+ record = service.read(id_=pid, identity=identity)._record
+ record.update(metadata)
+ # the refresh is required because the access system field takes precedence
+ # over the record's data in 'record.commit()'
+ record.access.refresh_from_dict(record["access"])
+ record.commit()
+ db.session.commit()
+ service.indexer.index(record)
+ else:
+ try:
+ # first, try the modern approach of updating records (March 2021)
+ service.update_draft(id_=pid, identity=identity, data=metadata)
+ service.publish(id_=pid, identity=identity)
+ except Exception as e:
+ # if that fails, try the good old plain update
+ click.secho("error: {}".format(e), fg="yellow")
+ click.secho("trying with service.update()...", fg="yellow")
+ service.update(id_=pid, identity=identity, data=metadata)
+
click.secho(pid, fg="green")
--
GitLab