cli (blog): add --comments-from to target an item comments node:
- add `--comments-from <item_id>` and `--comments-from-last` to automatically retrieve the
comments node of a blog post.
- ⚠️`--draft-path` short option moved from `-F` to `-d` (so `-F` can be used for
`--comments-from`).
This commit is contained in:
parent
45112fb22e
commit
25f1aa9178
2 changed files with 111 additions and 10 deletions
|
|
@ -439,7 +439,7 @@ class LiberviaCli:
|
|||
"-D", "--current", action="store_true", help=_("load current draft")
|
||||
)
|
||||
draft_group.add_argument(
|
||||
"-F", "--draft-path", type=Path, help=_("path to a draft file to retrieve")
|
||||
"-d", "--draft-path", type=Path, help=_("path to a draft file to retrieve")
|
||||
)
|
||||
|
||||
def make_pubsub_group(self, flags, defaults):
|
||||
|
|
|
|||
|
|
@ -143,11 +143,31 @@ class AltLinkAction(argparse.Action):
|
|||
alt_links.append(alt_link)
|
||||
|
||||
|
||||
class BlogPublishCommon:
|
||||
"""handle common option for publising commands (Set and Edit)"""
|
||||
class CommentsFromCommon:
|
||||
"""handle the --comments-from option"""
|
||||
|
||||
async def get_existing_item(self, service, node, item):
|
||||
"""Fetch the data of an existing item from the pubsub service.
|
||||
def add_comments_from_options(self):
|
||||
"""Add the --comments-from options to the parser"""
|
||||
group = self.parser.add_mutually_exclusive_group()
|
||||
group.add_argument(
|
||||
"-F",
|
||||
"--comments-from",
|
||||
nargs="?",
|
||||
const="",
|
||||
default=None,
|
||||
metavar="PARENT_ITEM_ID",
|
||||
help=_(
|
||||
"target the comments node of the given item (or URL item if provided)"
|
||||
),
|
||||
)
|
||||
group.add_argument(
|
||||
"--comments-from-last",
|
||||
action="store_true",
|
||||
help=_("target the comments node of the last item of the node"),
|
||||
)
|
||||
|
||||
async def get_item(self, service, node, item):
|
||||
"""Fetch an existing item from a pubsub service
|
||||
|
||||
@param service: JID of the pubsub service (None for PEP)
|
||||
@param node: identifier of the pubsub node (None for the default one)
|
||||
|
|
@ -163,6 +183,76 @@ class BlogPublishCommon:
|
|||
)
|
||||
return mb_data["items"][0]
|
||||
|
||||
def get_url_item(self):
|
||||
"""Return the item ID from the -u URL, if any
|
||||
|
||||
@return: item ID from the URL, None if there is no URL or no item in it
|
||||
"""
|
||||
url = self.args.pubsub_url
|
||||
if not url:
|
||||
return None
|
||||
if url.startswith("http"):
|
||||
url = self.host.get_xmpp_uri_from_http(url)
|
||||
return uri.parse_xmpp_uri(url).get("item")
|
||||
|
||||
def resolve_comments_args(self):
|
||||
"""Adjust the parsed args for the --comments-from option
|
||||
|
||||
The item from the -u URL is the parent item, not an item to process: the base
|
||||
class merged it in the item options, we retrieve it here.
|
||||
"""
|
||||
self.args.url_item = self.get_url_item()
|
||||
if self.args.comments_from == "" and not self.args.url_item:
|
||||
self.parser.error(
|
||||
_(
|
||||
"--comments-from without item ID can only be used "
|
||||
"with a -u URL containing an item"
|
||||
)
|
||||
)
|
||||
if self.args.url_item:
|
||||
if hasattr(self.args, "item"):
|
||||
if self.args.item == self.args.url_item:
|
||||
self.args.item = ""
|
||||
elif self.args.items == [self.args.url_item]:
|
||||
self.args.items = []
|
||||
|
||||
async def resolve_comments_from(self):
|
||||
"""Resolve the comments node and update the service and node args
|
||||
|
||||
The service/node options then locate the parent item, not the comments node.
|
||||
"""
|
||||
if self.args.comments_from is None and not self.args.comments_from_last:
|
||||
return
|
||||
self.resolve_comments_args()
|
||||
self.args.service, self.args.node = await self.resolve_comments_target()
|
||||
|
||||
async def resolve_comments_target(self):
|
||||
"""Return the (service, node) of the parent item's comments node."""
|
||||
if self.args.comments_from_last:
|
||||
parent_item = None
|
||||
else:
|
||||
parent_item = self.args.comments_from or self.args.url_item
|
||||
try:
|
||||
parent = await self.get_item(self.args.service, self.args.node, parent_item)
|
||||
except BridgeException as e:
|
||||
if e.classname == "NotFound":
|
||||
self.disp(f"parent item {parent_item!r} not found", error=True)
|
||||
self.host.quit(C.EXIT_NOT_FOUND)
|
||||
self.disp(f"can't get parent item: {e}", error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
comments = parent.get("comments")
|
||||
if not comments:
|
||||
self.disp(
|
||||
"parent item has no comments node (comments disabled?)",
|
||||
error=True,
|
||||
)
|
||||
self.host.quit(C.EXIT_DATA_ERROR)
|
||||
return comments[0]["service"], comments[0]["node"]
|
||||
|
||||
|
||||
class BlogPublishCommon(CommentsFromCommon):
|
||||
"""handle common option for publising commands (Set and Edit)"""
|
||||
|
||||
async def get_current_syntax(self):
|
||||
"""Retrieve current_syntax
|
||||
|
||||
|
|
@ -191,6 +281,7 @@ class BlogPublishCommon:
|
|||
return self.args.syntax
|
||||
|
||||
def add_parser_options(self):
|
||||
self.add_comments_from_options()
|
||||
self.parser.add_argument("-T", "--title", help=_("title of the item"))
|
||||
self.parser.add_argument(
|
||||
"-t",
|
||||
|
|
@ -382,6 +473,7 @@ class Set(base.CommandBase, BlogPublishCommon):
|
|||
|
||||
async def start(self):
|
||||
self.current_syntax = await self.get_current_syntax()
|
||||
await self.resolve_comments_from()
|
||||
self.pubsub_item = self.args.item
|
||||
if self.args.replace and not self.pubsub_item:
|
||||
self.parser.error("--replace can only be used with -i")
|
||||
|
|
@ -390,11 +482,11 @@ class Set(base.CommandBase, BlogPublishCommon):
|
|||
# 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(
|
||||
existing = await self.get_item(
|
||||
self.args.service, self.args.node, self.pubsub_item
|
||||
)
|
||||
except BridgeException as e:
|
||||
if e.condition == "item-not-found":
|
||||
if e.classname == "NotFound":
|
||||
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)
|
||||
|
|
@ -425,7 +517,7 @@ class Set(base.CommandBase, BlogPublishCommon):
|
|||
self.host.quit(C.EXIT_OK)
|
||||
|
||||
|
||||
class Get(base.CommandBase):
|
||||
class Get(base.CommandBase, CommentsFromCommon):
|
||||
TEMPLATE = "blog/articles.html"
|
||||
|
||||
def __init__(self, host):
|
||||
|
|
@ -443,7 +535,8 @@ class Get(base.CommandBase):
|
|||
)
|
||||
|
||||
def add_parser_options(self):
|
||||
# TODO: a key(s) argument to select keys to display
|
||||
self.add_comments_from_options()
|
||||
# TODO: a key(s) argument to select keys to display
|
||||
self.parser.add_argument(
|
||||
"-k",
|
||||
"--key",
|
||||
|
|
@ -607,6 +700,7 @@ class Get(base.CommandBase):
|
|||
print(("\n" + sep + "\n"))
|
||||
|
||||
async def start(self):
|
||||
await self.resolve_comments_from()
|
||||
try:
|
||||
mb_data = data_format.deserialise(
|
||||
await self.host.bridge.mb_get(
|
||||
|
|
@ -777,7 +871,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):
|
||||
item = await self.get_existing_item(service, node, item)
|
||||
item = await self.get_item(service, node, item)
|
||||
|
||||
try:
|
||||
content = item["content_xhtml"]
|
||||
|
|
@ -812,6 +906,13 @@ class Edit(base.CommandBase, BlogPublishCommon, common.BaseEdit):
|
|||
# if there are user defined extension, we use them
|
||||
SYNTAX_EXT.update(self.host.cli_settings.syntax_ext)
|
||||
self.current_syntax = await self.get_current_syntax()
|
||||
if self.args.comments_from is not None or self.args.comments_from_last:
|
||||
self.resolve_comments_args()
|
||||
if not self.args.item and not self.args.last_item:
|
||||
self.parser.error(
|
||||
_("edit with --comments-from requires -i (comment ID) or -L")
|
||||
)
|
||||
self.args.service, self.args.node = await self.resolve_comments_target()
|
||||
|
||||
(
|
||||
self.pubsub_service,
|
||||
|
|
|
|||
Loading…
Reference in a new issue