*** Wartungsfenster jeden ersten Mittwoch vormittag im Monat ***

Skip to content
Snippets Groups Projects
Commit ed3d997b authored by Moser, Maximilian's avatar Moser, Maximilian
Browse files

Add further CLI commands for draft management

* add commands for listing/adding/removing files from drafts
* add commands for listing/deleting drafts
parent 5d9ef990
No related branches found
No related tags found
No related merge requests found
......@@ -2,7 +2,8 @@
import json
import os
from os.path import basename
import sys
from os.path import basename, join, isfile, isdir
import click
from flask.cli import with_appcontext
......@@ -11,6 +12,7 @@ from invenio_access import any_user
from invenio_access.utils import get_identity
from invenio_accounts import current_accounts
from invenio_pidstore.models import PersistentIdentifier
from invenio_rdm_records.records.models import DraftMetadata
from invenio_rdm_records.services.services import (
BibliographicDraftFilesService as DraftFileService,
)
......@@ -52,6 +54,44 @@ def get_identity_for_user(user):
return identity
def convert_to_recid(pid_value, pid_type):
if pid_type != "recid":
pid_value = (
PersistentIdentifier.query.filter_by(pid_value=pid, pid_type=pid_type)
.first()
.pid_value
)
return pid_value
option_as_user = click.option(
"--as-user",
"-u",
"user",
metavar="USER",
default=None,
required=True,
help="email address of the user to use for record creation",
)
option_pid_type = click.option(
"--type",
"-t",
"pid_type",
metavar="PID_TYPE",
default="recid",
help="pid type (default: 'recid')",
)
option_pid_value = click.option(
"--pid",
"-p",
"pid",
metavar="PID_VALUE",
required=True,
help="persistent identifier of the record draft to operate on",
)
@click.group()
def utilities():
"""Utility commands for InvenioRDM."""
......@@ -64,16 +104,15 @@ def draft():
pass
@draft.group()
def files():
"""Manage files deposited with the draft."""
pass
@draft.command("create")
@click.argument("metadata_path")
@click.option(
"--as-user",
"-u",
"user",
default=None,
metavar="USER",
help="email address of the user to use for record creation (default: the first user)",
)
@option_as_user
@click.option(
"--publish",
"-p",
......@@ -87,71 +126,185 @@ def create_draft(metadata_path, publish, user):
recid = None
identity = get_identity_for_user(user)
if os.path.isfile(metadata_path):
if isfile(metadata_path):
draft = create_record_from_metadata(metadata_path, identity)
recid = draft["id"]
elif os.path.isdir(metadata_path):
metadata_file_path = os.path.join(metadata_path, "metadata.json")
deposit_files_path = os.path.join(metadata_path, "files")
if not os.path.isfile(metadata_file_path):
elif isdir(metadata_path):
metadata_file_path = join(metadata_path, "metadata.json")
deposit_files_path = join(metadata_path, "files")
if not isfile(metadata_file_path):
raise Exception("metadata file does not exist: %s" % metadata_file_path)
draft = create_record_from_metadata(metadata_file_path, identity)
recid = draft["id"]
file_names = []
if os.path.isdir(deposit_files_path):
file_names = [os.path.basename(fn) for fn in os.listdir(deposit_files_path)]
if isdir(deposit_files_path):
dir_contents = os.listdir(deposit_files_path)
file_names = [basename(fn) for fn in dir_contents if isfile(join(deposit_files_path, fn))]
if len(dir_contents) != len(file_names):
ignored = [basename(fn) for fn in dir_contents if not isfile(join(deposit_files_path, fn))]
click.secho(
"ignored in '{}': {}".format(deposit_files_path, ignored),
fg="red",
err=True,
)
service = DraftFileService()
service.init_files(recid, identity, [{"key": fn} for fn in file_names])
service.init_files(
id_=recid, identity=identity, data=[{"key": fn} for fn in file_names]
)
for fn in file_names:
file_path = os.path.join(deposit_files_path, fn)
file_path = join(deposit_files_path, fn)
with open(file_path, "rb") as deposit_file:
service.set_file_content(recid, fn, identity, deposit_file)
service.set_file_content(
id_=recid, file_key=fn, identity=identity, stream=deposit_file
)
service.commit_file(recid, fn, identity)
service.commit_file(id_=recid, file_key=fn, identity=identity)
else:
raise Exception("neither a file nor a directory: %s" % metadata_path)
if publish:
service = RecordService()
service.publish(recid, identity)
service.publish(id_=recid, identity=identity)
click.secho(recid, fg="green")
@draft.command("list")
@option_as_user
@with_appcontext
def create_draft(user):
"""List all drafts accessible to the given user."""
identity = get_identity_for_user(user)
service = RecordService()
recids = [
dm.json["id"]
for dm in DraftMetadata.query.all()
if dm is not None and dm.json is not None
]
for recid in recids:
try:
draft = service.read_draft(id_=recid, identity=identity)
click.secho(
"{} - {}".format(draft.id, draft.data["metadata"]["title"]), fg="green"
)
except:
pass
click.echo(recid)
@draft.command("delete")
@option_pid_value
@option_pid_type
@option_as_user
@with_appcontext
def publish_draft(pid, pid_type, user):
"""Delete the specified draft."""
pid = convert_to_recid(pid, pid_type)
identity = get_identity_for_user(user)
service = RecordService()
service.delete_draft(id_=pid, identity=identity)
click.secho(pid, fg="green")
@draft.command("publish")
@click.argument("pid", metavar="PID_VALUE")
@click.option(
"--as-user",
"-u",
"user",
default=None,
metavar="USER",
help="email address of the user to use for record creation (default: the first user)",
)
@click.option(
"--type",
"-t",
"pid_type",
default="recid",
metavar="PID_TYPE",
help="pid type (default: 'recid')",
)
@option_pid_value
@option_pid_type
@option_as_user
@with_appcontext
def publish_draft(pid, pid_type, user):
"""Publish the specified draft."""
if pid_type != "recid":
pid = (
PersistentIdentifier.query.filter_by(pid_value=pid, pid_type=pid_type)
.first()
.pid_value
)
pid_type = "recid"
pid = convert_to_recid(pid, pid_type)
identity = get_identity_for_user(user)
service = RecordService()
service.publish(pid, identity)
click.echo(pid)
service.publish(id_=pid, identity=identity)
click.secho(pid, fg="green")
@files.command("add")
@click.argument("filepaths", metavar="PATH", type=click.Path(exists=True), nargs=-1)
@option_pid_value
@option_pid_type
@option_as_user
@with_appcontext
def add_files(filepaths, pid, pid_type, user):
"""Add the specified files to the draft."""
recid = convert_to_recid(pid, pid_type)
identity = get_identity_for_user(user)
service = DraftFileService()
paths = []
for file_path in filepaths:
if isdir(file_path):
# add all files (no recursion into sub-dirs) from the directory
dir_contents = os.listdir(file_path)
file_names = [
basename(fn) for fn in dir_contents if isfile(join(file_path, fn))
]
if len(dir_contents) != len(file_names):
ignored = [
basename(fn)
for fn in dir_contents
if not isfile(join(file_path, fn))
]
click.secho(
"ignored in '{}': {}".format(file_path, ignored), fg="red", err=True
)
paths_ = [join(file_path, fn) for fn in file_names]
paths.extend(paths_)
elif isfile(file_path):
paths.append(file_path)
keys = [basename(fp) for fp in paths]
if len(set(keys)) != len(keys):
click.secho("aborting: duplicates in file names detected", fg="red", err=True)
sys.exit(1)
service.init_files(
id_=recid, identity=identity, data=[{"key": basename(fp)} for fp in paths]
)
for fp in paths:
fn = basename(fp)
with open(file_path, "rb") as deposit_file:
service.set_file_content(
id_=recid, file_key=fn, identity=identity, stream=deposit_file
)
service.commit_file(id_=recid, file_key=fn, identity=identity)
click.secho(recid, fg="green")
@files.command("remove")
@click.argument("filekeys", metavar="FILE", nargs=-1)
@option_pid_value
@option_pid_type
@option_as_user
@with_appcontext
def remove_files(filekeys, pid, pid_type, user):
"""Remove the deposited files."""
recid = convert_to_recid(pid, pid_type)
identity = get_identity_for_user(user)
service = DraftFileService()
for file_key in filekeys:
service.delete_file(id_=recid, file_key=file_key, identity=identity)
@files.command("list")
@option_pid_value
@option_pid_type
@option_as_user
@with_appcontext
def list_files(pid, pid_type, user):
"""Show a list of files deposited with the draft."""
recid = convert_to_recid(pid, pid_type)
identity = get_identity_for_user(user)
service = DraftFileService()
file_results = service.list_files(id_=recid, identity=identity)
for f in file_results.entries:
click.echo(f)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment