jp (pubsub/node): new "import" command, to publish many nodes from an XML file
This commit is contained in:
parent
d747c46736
commit
bb5a2befc5
2 changed files with 92 additions and 1 deletions
|
|
@ -315,6 +315,92 @@ class NodeSet(base.CommandBase):
|
|||
)
|
||||
|
||||
|
||||
class NodeImport(base.CommandBase):
|
||||
|
||||
def __init__(self, host):
|
||||
super(NodeImport, self).__init__(
|
||||
host,
|
||||
"import",
|
||||
use_pubsub=True,
|
||||
pubsub_flags={C.NODE},
|
||||
help=_(u"import raw XML to a node"),
|
||||
)
|
||||
self.need_loop = True
|
||||
|
||||
def add_parser_options(self):
|
||||
self.parser.add_argument(
|
||||
"--admin",
|
||||
action="store_true",
|
||||
help=_(u"do a pubsub admin request, needed to change publisher"),
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"import_file",
|
||||
type=file,
|
||||
help=_(u"path to the XML file with data to import. The file must contain "
|
||||
u"whole XML of each item to import."),
|
||||
)
|
||||
|
||||
def psItemsSendCb(self, item_ids):
|
||||
self.disp(_(u'items published with id(s) {item_ids}').format(
|
||||
item_ids=u', '.join(item_ids)))
|
||||
self.host.quit()
|
||||
|
||||
def start(self):
|
||||
try:
|
||||
element, etree = xml_tools.etreeParse(self, self.args.import_file,
|
||||
reraise=True)
|
||||
except Exception as e:
|
||||
from lxml.etree import XMLSyntaxError
|
||||
if isinstance(e, XMLSyntaxError) and e.code == 5:
|
||||
# we have extra content, this probaby means that item are not wrapped
|
||||
# so we wrap them here and try again
|
||||
self.args.import_file.seek(0)
|
||||
xml_buf = "<import>" + self.args.import_file.read() + "</import>"
|
||||
element, etree = xml_tools.etreeParse(self, xml_buf)
|
||||
|
||||
# we reverse element as we expect to have most recently published element first
|
||||
# TODO: make this more explicit and add an option
|
||||
element[:] = reversed(element)
|
||||
|
||||
if not all([i.tag == '{http://jabber.org/protocol/pubsub}item' for i in element]):
|
||||
self.disp(
|
||||
_(u"You are not using list of pubsub items, we can't import this file"),
|
||||
error=True)
|
||||
self.host.quit(C.EXIT_DATA_ERROR)
|
||||
|
||||
items = [etree.tostring(i, encoding="utf-8") for i in element]
|
||||
if self.args.admin:
|
||||
self.host.bridge.psAdminItemsSend(
|
||||
self.args.service,
|
||||
self.args.node,
|
||||
items,
|
||||
u"",
|
||||
self.profile,
|
||||
callback=partial(self.psItemsSendCb),
|
||||
errback=partial(
|
||||
self.errback,
|
||||
msg=_(u"can't send item: {}"),
|
||||
exit_code=C.EXIT_BRIDGE_ERRBACK,
|
||||
),
|
||||
)
|
||||
else:
|
||||
self.disp(_(u"Items are imported without using admin mode, publisher can't "
|
||||
u"be changed"))
|
||||
self.host.bridge.psItemsSend(
|
||||
self.args.service,
|
||||
self.args.node,
|
||||
items,
|
||||
u"",
|
||||
self.profile,
|
||||
callback=partial(self.psItemsSendCb),
|
||||
errback=partial(
|
||||
self.errback,
|
||||
msg=_(u"can't send item: {}"),
|
||||
exit_code=C.EXIT_BRIDGE_ERRBACK,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class NodeAffiliationsGet(base.CommandBase):
|
||||
def __init__(self, host):
|
||||
base.CommandBase.__init__(
|
||||
|
|
@ -696,6 +782,7 @@ class Node(base.CommandBase):
|
|||
NodePurge,
|
||||
NodeDelete,
|
||||
NodeSet,
|
||||
NodeImport,
|
||||
NodeAffiliations,
|
||||
NodeSubscriptions,
|
||||
NodeSchema,
|
||||
|
|
|
|||
|
|
@ -20,11 +20,13 @@
|
|||
from sat.core.i18n import _
|
||||
from sat_frontends.jp.constants import Const as C
|
||||
|
||||
def etreeParse(cmd, raw_xml):
|
||||
def etreeParse(cmd, raw_xml, reraise=False):
|
||||
"""Import lxml and parse raw XML
|
||||
|
||||
@param cmd(CommandBase): current command instance
|
||||
@param raw_xml(file, str): an XML bytestring, string or file-like object
|
||||
@param reraise(bool): if True, re raise exception on parse error instead of doing a
|
||||
parser.error (which terminate the execution)
|
||||
@return (tuple(etree.Element, module): parsed element, etree module
|
||||
"""
|
||||
try:
|
||||
|
|
@ -42,6 +44,8 @@ def etreeParse(cmd, raw_xml):
|
|||
else:
|
||||
element = etree.parse(raw_xml).getroot()
|
||||
except Exception as e:
|
||||
if reraise:
|
||||
raise e
|
||||
cmd.parser.error(
|
||||
_(u"Can't parse the payload XML in input: {msg}").format(msg=e)
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue