cli (blog): preserve existing item fields on set -i + attachments fixes:
- `set -i` was replacing all fields of any existing item, losing tags, attachments, publication date, etc. It now fetches the existing item if any, and starts from its data. `-r/--replace` can be used to force a full replacement (and avoid fetching old item). - `--attachment` uses `action="extend"` so multiple `-a` can be used. - Fix attachement data key (`url` -> `sources`).
This commit is contained in:
parent
8afde9962a
commit
fa04667152
1 changed files with 53 additions and 14 deletions
|
|
@ -39,6 +39,7 @@ from libervia.backend.tools.common import data_format
|
|||
from libervia.backend.tools.common.ansi import ANSI as A
|
||||
from libervia.cli import common
|
||||
from libervia.cli.constants import Const as C
|
||||
from libervia.frontends.bridge.bridge_frontend import BridgeException
|
||||
|
||||
from . import base, cmd_pubsub
|
||||
|
||||
|
|
@ -145,6 +146,23 @@ class AltLinkAction(argparse.Action):
|
|||
class BlogPublishCommon:
|
||||
"""handle common option for publising commands (Set and Edit)"""
|
||||
|
||||
async def get_existing_item(self, service, node, item):
|
||||
"""Fetch the data of an existing item from the pubsub service.
|
||||
|
||||
@param service: JID of the pubsub service (None for PEP)
|
||||
@param node: identifier of the pubsub node (None for the default one)
|
||||
@param item: ID of the item to fetch (None for the latest item)
|
||||
@return: deserialised data of the item
|
||||
@raise BridgeException: if the item can't be fetched (e.g. "item-not-found")
|
||||
"""
|
||||
items = [item] if item else []
|
||||
mb_data = data_format.deserialise(
|
||||
await self.host.bridge.mb_get(
|
||||
service, node, 1, items, data_format.serialise({}), self.profile
|
||||
)
|
||||
)
|
||||
return mb_data["items"][0]
|
||||
|
||||
async def get_current_syntax(self):
|
||||
"""Retrieve current_syntax
|
||||
|
||||
|
|
@ -190,6 +208,7 @@ class BlogPublishCommon:
|
|||
"-a",
|
||||
"--attachment",
|
||||
dest="attachments",
|
||||
action="extend",
|
||||
nargs="+",
|
||||
help=_("attachment in the form URL [metadata_name=value]"),
|
||||
)
|
||||
|
|
@ -282,13 +301,13 @@ class BlogPublishCommon:
|
|||
f" accepted): {arg}"
|
||||
)
|
||||
if attachment:
|
||||
# if we hae a new URL, we have a new attachment
|
||||
# if we have a new URL, we have a new attachment
|
||||
attachments.append(attachment)
|
||||
attachment = {}
|
||||
attachment["url"] = arg
|
||||
attachment["sources"] = [{"url": arg}]
|
||||
else:
|
||||
# we should have a metadata
|
||||
if "url" not in attachment:
|
||||
if "sources" not in attachment:
|
||||
self.parser.error(
|
||||
"you must to specify an URL before any metadata in "
|
||||
"--attachment"
|
||||
|
|
@ -351,13 +370,40 @@ class Set(base.CommandBase, BlogPublishCommon):
|
|||
|
||||
def add_parser_options(self):
|
||||
BlogPublishCommon.add_parser_options(self)
|
||||
self.parser.add_argument(
|
||||
"-r",
|
||||
"--replace",
|
||||
action="store_true",
|
||||
help=_(
|
||||
"don't fetch the existing item, replace all its fields with "
|
||||
"the given ones (only used with -i)"
|
||||
),
|
||||
)
|
||||
|
||||
async def start(self):
|
||||
self.current_syntax = await self.get_current_syntax()
|
||||
self.pubsub_item = self.args.item
|
||||
mb_data = {
|
||||
"service": self.args.service or None,
|
||||
}
|
||||
if self.args.replace and not self.pubsub_item:
|
||||
self.parser.error("--replace can only be used with -i")
|
||||
mb_data = {}
|
||||
if self.pubsub_item and not self.args.replace:
|
||||
# start from the existing item data, so fields not given on the command line
|
||||
# (tags, attachments, publication date, etc.) are kept
|
||||
try:
|
||||
existing = await self.get_existing_item(
|
||||
self.args.service, self.args.node, self.pubsub_item
|
||||
)
|
||||
except BridgeException as e:
|
||||
if e.condition == "item-not-found":
|
||||
self.disp(f"item {self.pubsub_item!r} not found, creating a new one")
|
||||
else:
|
||||
self.disp(f"can't get item: {e}", error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
for key in KEY_TO_REMOVE_METADATA:
|
||||
existing.pop(key, None)
|
||||
mb_data.update(existing)
|
||||
mb_data["service"] = self.args.service or None
|
||||
if self.args.node:
|
||||
mb_data["node"] = self.args.node
|
||||
self.set_mb_data_from_args(mb_data)
|
||||
|
|
@ -731,14 +777,7 @@ class Edit(base.CommandBase, BlogPublishCommon, common.BaseEdit):
|
|||
return SYNTAX_EXT.get(self.current_syntax, SYNTAX_EXT[""])
|
||||
|
||||
async def get_item_data(self, service, node, item):
|
||||
items = [item] if item else []
|
||||
|
||||
mb_data = data_format.deserialise(
|
||||
await self.host.bridge.mb_get(
|
||||
service, node, 1, items, data_format.serialise({}), self.profile
|
||||
)
|
||||
)
|
||||
item = mb_data["items"][0]
|
||||
item = await self.get_existing_item(service, node, item)
|
||||
|
||||
try:
|
||||
content = item["content_xhtml"]
|
||||
|
|
|
|||
Loading…
Reference in a new issue