Mercurial > libervia-backend
comparison sat_frontends/jp/cmd_pubsub.py @ 2624:56f94936df1e
code style reformatting using black
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 27 Jun 2018 20:14:46 +0200 |
parents | 26edcf3a30eb |
children | 4b693ea24d5f |
comparison
equal
deleted
inserted
replaced
2623:49533de4540b | 2624:56f94936df1e |
---|---|
36 | 36 |
37 __commands__ = ["Pubsub"] | 37 __commands__ = ["Pubsub"] |
38 | 38 |
39 PUBSUB_TMP_DIR = u"pubsub" | 39 PUBSUB_TMP_DIR = u"pubsub" |
40 PUBSUB_SCHEMA_TMP_DIR = PUBSUB_TMP_DIR + "_schema" | 40 PUBSUB_SCHEMA_TMP_DIR = PUBSUB_TMP_DIR + "_schema" |
41 ALLOWED_SUBSCRIPTIONS_OWNER = ('subscribed', 'pending', 'none') | 41 ALLOWED_SUBSCRIPTIONS_OWNER = ("subscribed", "pending", "none") |
42 | 42 |
43 # TODO: need to split this class in several modules, plugin should handle subcommands | 43 # TODO: need to split this class in several modules, plugin should handle subcommands |
44 | 44 |
45 | 45 |
46 class NodeInfo(base.CommandBase): | 46 class NodeInfo(base.CommandBase): |
47 | 47 def __init__(self, host): |
48 def __init__(self, host): | 48 base.CommandBase.__init__( |
49 base.CommandBase.__init__(self, host, 'info', use_output=C.OUTPUT_DICT, use_pubsub=True, pubsub_flags={C.NODE}, help=_(u'retrieve node configuration')) | 49 self, |
50 self.need_loop=True | 50 host, |
51 | 51 "info", |
52 def add_parser_options(self): | 52 use_output=C.OUTPUT_DICT, |
53 self.parser.add_argument("-k", "--key", type=base.unicode_decoder, action='append', dest='keys', | 53 use_pubsub=True, |
54 help=_(u"data key to filter")) | 54 pubsub_flags={C.NODE}, |
55 help=_(u"retrieve node configuration"), | |
56 ) | |
57 self.need_loop = True | |
58 | |
59 def add_parser_options(self): | |
60 self.parser.add_argument( | |
61 "-k", | |
62 "--key", | |
63 type=base.unicode_decoder, | |
64 action="append", | |
65 dest="keys", | |
66 help=_(u"data key to filter"), | |
67 ) | |
55 | 68 |
56 def removePrefix(self, key): | 69 def removePrefix(self, key): |
57 return key[7:] if key.startswith(u"pubsub#") else key | 70 return key[7:] if key.startswith(u"pubsub#") else key |
58 | 71 |
59 def filterKey(self, key): | 72 def filterKey(self, key): |
60 return any((key == k or key == u'pubsub#' + k) for k in self.args.keys) | 73 return any((key == k or key == u"pubsub#" + k) for k in self.args.keys) |
61 | 74 |
62 def psNodeConfigurationGetCb(self, config_dict): | 75 def psNodeConfigurationGetCb(self, config_dict): |
63 key_filter = (lambda k: True) if not self.args.keys else self.filterKey | 76 key_filter = (lambda k: True) if not self.args.keys else self.filterKey |
64 config_dict = {self.removePrefix(k):v for k,v in config_dict.iteritems() if key_filter(k)} | 77 config_dict = { |
78 self.removePrefix(k): v for k, v in config_dict.iteritems() if key_filter(k) | |
79 } | |
65 self.output(config_dict) | 80 self.output(config_dict) |
66 self.host.quit() | 81 self.host.quit() |
67 | 82 |
68 def psNodeConfigurationGetEb(self, failure_): | 83 def psNodeConfigurationGetEb(self, failure_): |
69 self.disp(u"can't get node configuration: {reason}".format( | 84 self.disp( |
70 reason=failure_), error=True) | 85 u"can't get node configuration: {reason}".format(reason=failure_), error=True |
86 ) | |
71 self.host.quit(C.EXIT_BRIDGE_ERRBACK) | 87 self.host.quit(C.EXIT_BRIDGE_ERRBACK) |
72 | 88 |
73 def start(self): | 89 def start(self): |
74 self.host.bridge.psNodeConfigurationGet( | 90 self.host.bridge.psNodeConfigurationGet( |
75 self.args.service, | 91 self.args.service, |
76 self.args.node, | 92 self.args.node, |
77 self.profile, | 93 self.profile, |
78 callback=self.psNodeConfigurationGetCb, | 94 callback=self.psNodeConfigurationGetCb, |
79 errback=self.psNodeConfigurationGetEb) | 95 errback=self.psNodeConfigurationGetEb, |
96 ) | |
80 | 97 |
81 | 98 |
82 class NodeCreate(base.CommandBase): | 99 class NodeCreate(base.CommandBase): |
83 | 100 def __init__(self, host): |
84 def __init__(self, host): | 101 base.CommandBase.__init__( |
85 base.CommandBase.__init__(self, host, 'create', use_output=C.OUTPUT_DICT, use_pubsub=True, pubsub_flags={C.NODE}, use_verbose=True, help=_(u'create a node')) | 102 self, |
86 self.need_loop=True | 103 host, |
87 | 104 "create", |
88 def add_parser_options(self): | 105 use_output=C.OUTPUT_DICT, |
89 self.parser.add_argument("-f", "--field", type=base.unicode_decoder, action='append', nargs=2, dest='fields', | 106 use_pubsub=True, |
90 default=[], metavar=(u"KEY", u"VALUE"), help=_(u"configuration field to set")) | 107 pubsub_flags={C.NODE}, |
91 self.parser.add_argument("-F", "--full-prefix", action="store_true", help=_(u"don't prepend \"pubsub#\" prefix to field names")) | 108 use_verbose=True, |
109 help=_(u"create a node"), | |
110 ) | |
111 self.need_loop = True | |
112 | |
113 def add_parser_options(self): | |
114 self.parser.add_argument( | |
115 "-f", | |
116 "--field", | |
117 type=base.unicode_decoder, | |
118 action="append", | |
119 nargs=2, | |
120 dest="fields", | |
121 default=[], | |
122 metavar=(u"KEY", u"VALUE"), | |
123 help=_(u"configuration field to set"), | |
124 ) | |
125 self.parser.add_argument( | |
126 "-F", | |
127 "--full-prefix", | |
128 action="store_true", | |
129 help=_(u'don\'t prepend "pubsub#" prefix to field names'), | |
130 ) | |
92 | 131 |
93 def psNodeCreateCb(self, node_id): | 132 def psNodeCreateCb(self, node_id): |
94 if self.host.verbosity: | 133 if self.host.verbosity: |
95 announce = _(u'node created successfully: ') | 134 announce = _(u"node created successfully: ") |
96 else: | 135 else: |
97 announce = u'' | 136 announce = u"" |
98 self.disp(announce + node_id) | 137 self.disp(announce + node_id) |
99 self.host.quit() | 138 self.host.quit() |
100 | 139 |
101 def psNodeCreateEb(self, failure_): | 140 def psNodeCreateEb(self, failure_): |
102 self.disp(u"can't create: {reason}".format( | 141 self.disp(u"can't create: {reason}".format(reason=failure_), error=True) |
103 reason=failure_), error=True) | |
104 self.host.quit(C.EXIT_BRIDGE_ERRBACK) | 142 self.host.quit(C.EXIT_BRIDGE_ERRBACK) |
105 | 143 |
106 def start(self): | 144 def start(self): |
107 if not self.args.full_prefix: | 145 if not self.args.full_prefix: |
108 options = {u'pubsub#' + k: v for k,v in self.args.fields} | 146 options = {u"pubsub#" + k: v for k, v in self.args.fields} |
109 else: | 147 else: |
110 options = dict(self.args.fields) | 148 options = dict(self.args.fields) |
111 self.host.bridge.psNodeCreate( | 149 self.host.bridge.psNodeCreate( |
112 self.args.service, | 150 self.args.service, |
113 self.args.node, | 151 self.args.node, |
114 options, | 152 options, |
115 self.profile, | 153 self.profile, |
116 callback=self.psNodeCreateCb, | 154 callback=self.psNodeCreateCb, |
117 errback=partial(self.errback, | 155 errback=partial( |
118 msg=_(u"can't create node: {}"), | 156 self.errback, |
119 exit_code=C.EXIT_BRIDGE_ERRBACK)) | 157 msg=_(u"can't create node: {}"), |
158 exit_code=C.EXIT_BRIDGE_ERRBACK, | |
159 ), | |
160 ) | |
120 | 161 |
121 | 162 |
122 class NodeDelete(base.CommandBase): | 163 class NodeDelete(base.CommandBase): |
123 | 164 def __init__(self, host): |
124 def __init__(self, host): | 165 base.CommandBase.__init__( |
125 base.CommandBase.__init__(self, host, 'delete', use_pubsub=True, pubsub_flags={C.NODE}, help=_(u'delete a node')) | 166 self, |
126 self.need_loop=True | 167 host, |
127 | 168 "delete", |
128 def add_parser_options(self): | 169 use_pubsub=True, |
129 self.parser.add_argument('-f', '--force', action='store_true', help=_(u'delete node without confirmation')) | 170 pubsub_flags={C.NODE}, |
171 help=_(u"delete a node"), | |
172 ) | |
173 self.need_loop = True | |
174 | |
175 def add_parser_options(self): | |
176 self.parser.add_argument( | |
177 "-f", | |
178 "--force", | |
179 action="store_true", | |
180 help=_(u"delete node without confirmation"), | |
181 ) | |
130 | 182 |
131 def psNodeDeleteCb(self): | 183 def psNodeDeleteCb(self): |
132 self.disp(_(u'node [{node}] deleted successfully').format(node=self.args.node)) | 184 self.disp(_(u"node [{node}] deleted successfully").format(node=self.args.node)) |
133 self.host.quit() | 185 self.host.quit() |
134 | 186 |
135 def start(self): | 187 def start(self): |
136 if not self.args.force: | 188 if not self.args.force: |
137 if not self.args.service: | 189 if not self.args.service: |
138 message = _(u"Are you sure to delete pep node [{node_id}] ?").format( | 190 message = _(u"Are you sure to delete pep node [{node_id}] ?").format( |
139 node_id=self.args.node) | 191 node_id=self.args.node |
192 ) | |
140 else: | 193 else: |
141 message = _(u"Are you sure to delete node [{node_id}] on service [{service}] ?").format( | 194 message = _( |
142 node_id=self.args.node, service=self.args.service) | 195 u"Are you sure to delete node [{node_id}] on service [{service}] ?" |
196 ).format(node_id=self.args.node, service=self.args.service) | |
143 self.host.confirmOrQuit(message, _(u"node deletion cancelled")) | 197 self.host.confirmOrQuit(message, _(u"node deletion cancelled")) |
144 | 198 |
145 self.host.bridge.psNodeDelete( | 199 self.host.bridge.psNodeDelete( |
146 self.args.service, | 200 self.args.service, |
147 self.args.node, | 201 self.args.node, |
148 self.profile, | 202 self.profile, |
149 callback=self.psNodeDeleteCb, | 203 callback=self.psNodeDeleteCb, |
150 errback=partial(self.errback, | 204 errback=partial( |
151 msg=_(u"can't delete node: {}"), | 205 self.errback, |
152 exit_code=C.EXIT_BRIDGE_ERRBACK)) | 206 msg=_(u"can't delete node: {}"), |
207 exit_code=C.EXIT_BRIDGE_ERRBACK, | |
208 ), | |
209 ) | |
153 | 210 |
154 | 211 |
155 class NodeSet(base.CommandBase): | 212 class NodeSet(base.CommandBase): |
156 | 213 def __init__(self, host): |
157 def __init__(self, host): | 214 base.CommandBase.__init__( |
158 base.CommandBase.__init__(self, host, 'set', use_output=C.OUTPUT_DICT, use_pubsub=True, pubsub_flags={C.NODE}, use_verbose=True, help=_(u'set node configuration')) | 215 self, |
159 self.need_loop=True | 216 host, |
160 | 217 "set", |
161 def add_parser_options(self): | 218 use_output=C.OUTPUT_DICT, |
162 self.parser.add_argument("-f", "--field", type=base.unicode_decoder, action='append', nargs=2, dest='fields', | 219 use_pubsub=True, |
163 required=True, metavar=(u"KEY", u"VALUE"), help=_(u"configuration field to set (required)")) | 220 pubsub_flags={C.NODE}, |
221 use_verbose=True, | |
222 help=_(u"set node configuration"), | |
223 ) | |
224 self.need_loop = True | |
225 | |
226 def add_parser_options(self): | |
227 self.parser.add_argument( | |
228 "-f", | |
229 "--field", | |
230 type=base.unicode_decoder, | |
231 action="append", | |
232 nargs=2, | |
233 dest="fields", | |
234 required=True, | |
235 metavar=(u"KEY", u"VALUE"), | |
236 help=_(u"configuration field to set (required)"), | |
237 ) | |
164 | 238 |
165 def psNodeConfigurationSetCb(self): | 239 def psNodeConfigurationSetCb(self): |
166 self.disp(_(u'node configuration successful'), 1) | 240 self.disp(_(u"node configuration successful"), 1) |
167 self.host.quit() | 241 self.host.quit() |
168 | 242 |
169 def psNodeConfigurationSetEb(self, failure_): | 243 def psNodeConfigurationSetEb(self, failure_): |
170 self.disp(u"can't set node configuration: {reason}".format( | 244 self.disp( |
171 reason=failure_), error=True) | 245 u"can't set node configuration: {reason}".format(reason=failure_), error=True |
246 ) | |
172 self.host.quit(C.EXIT_BRIDGE_ERRBACK) | 247 self.host.quit(C.EXIT_BRIDGE_ERRBACK) |
173 | 248 |
174 def getKeyName(self, k): | 249 def getKeyName(self, k): |
175 if not k.startswith(u'pubsub#'): | 250 if not k.startswith(u"pubsub#"): |
176 return u'pubsub#' + k | 251 return u"pubsub#" + k |
177 else: | 252 else: |
178 return k | 253 return k |
179 | 254 |
180 def start(self): | 255 def start(self): |
181 self.host.bridge.psNodeConfigurationSet( | 256 self.host.bridge.psNodeConfigurationSet( |
182 self.args.service, | 257 self.args.service, |
183 self.args.node, | 258 self.args.node, |
184 {self.getKeyName(k): v for k,v in self.args.fields}, | 259 {self.getKeyName(k): v for k, v in self.args.fields}, |
185 self.profile, | 260 self.profile, |
186 callback=self.psNodeConfigurationSetCb, | 261 callback=self.psNodeConfigurationSetCb, |
187 errback=self.psNodeConfigurationSetEb) | 262 errback=self.psNodeConfigurationSetEb, |
263 ) | |
188 | 264 |
189 | 265 |
190 class NodeAffiliationsGet(base.CommandBase): | 266 class NodeAffiliationsGet(base.CommandBase): |
191 | 267 def __init__(self, host): |
192 def __init__(self, host): | 268 base.CommandBase.__init__( |
193 base.CommandBase.__init__(self, host, 'get', use_output=C.OUTPUT_DICT, use_pubsub=True, pubsub_flags={C.NODE}, help=_(u'retrieve node affiliations (for node owner)')) | 269 self, |
194 self.need_loop=True | 270 host, |
271 "get", | |
272 use_output=C.OUTPUT_DICT, | |
273 use_pubsub=True, | |
274 pubsub_flags={C.NODE}, | |
275 help=_(u"retrieve node affiliations (for node owner)"), | |
276 ) | |
277 self.need_loop = True | |
195 | 278 |
196 def add_parser_options(self): | 279 def add_parser_options(self): |
197 pass | 280 pass |
198 | 281 |
199 def psNodeAffiliationsGetCb(self, affiliations): | 282 def psNodeAffiliationsGetCb(self, affiliations): |
200 self.output(affiliations) | 283 self.output(affiliations) |
201 self.host.quit() | 284 self.host.quit() |
202 | 285 |
203 def psNodeAffiliationsGetEb(self, failure_): | 286 def psNodeAffiliationsGetEb(self, failure_): |
204 self.disp(u"can't get node affiliations: {reason}".format( | 287 self.disp( |
205 reason=failure_), error=True) | 288 u"can't get node affiliations: {reason}".format(reason=failure_), error=True |
289 ) | |
206 self.host.quit(C.EXIT_BRIDGE_ERRBACK) | 290 self.host.quit(C.EXIT_BRIDGE_ERRBACK) |
207 | 291 |
208 def start(self): | 292 def start(self): |
209 self.host.bridge.psNodeAffiliationsGet( | 293 self.host.bridge.psNodeAffiliationsGet( |
210 self.args.service, | 294 self.args.service, |
211 self.args.node, | 295 self.args.node, |
212 self.profile, | 296 self.profile, |
213 callback=self.psNodeAffiliationsGetCb, | 297 callback=self.psNodeAffiliationsGetCb, |
214 errback=self.psNodeAffiliationsGetEb) | 298 errback=self.psNodeAffiliationsGetEb, |
299 ) | |
215 | 300 |
216 | 301 |
217 class NodeAffiliationsSet(base.CommandBase): | 302 class NodeAffiliationsSet(base.CommandBase): |
218 | 303 def __init__(self, host): |
219 def __init__(self, host): | 304 base.CommandBase.__init__( |
220 base.CommandBase.__init__(self, host, 'set', use_pubsub=True, pubsub_flags={C.NODE}, use_verbose=True, help=_(u'set affiliations (for node owner)')) | 305 self, |
221 self.need_loop=True | 306 host, |
307 "set", | |
308 use_pubsub=True, | |
309 pubsub_flags={C.NODE}, | |
310 use_verbose=True, | |
311 help=_(u"set affiliations (for node owner)"), | |
312 ) | |
313 self.need_loop = True | |
222 | 314 |
223 def add_parser_options(self): | 315 def add_parser_options(self): |
224 # XXX: we use optional argument syntax for a required one because list of list of 2 elements | 316 # XXX: we use optional argument syntax for a required one because list of list of 2 elements |
225 # (uses to construct dicts) don't work with positional arguments | 317 # (uses to construct dicts) don't work with positional arguments |
226 self.parser.add_argument("-a", | 318 self.parser.add_argument( |
227 "--affiliation", | 319 "-a", |
228 dest="affiliations", | 320 "--affiliation", |
229 metavar=('JID', 'AFFILIATION'), | 321 dest="affiliations", |
230 required=True, | 322 metavar=("JID", "AFFILIATION"), |
231 type=base.unicode_decoder, | 323 required=True, |
232 action="append", | 324 type=base.unicode_decoder, |
233 nargs=2, | 325 action="append", |
234 help=_(u"entity/affiliation couple(s)")) | 326 nargs=2, |
327 help=_(u"entity/affiliation couple(s)"), | |
328 ) | |
235 | 329 |
236 def psNodeAffiliationsSetCb(self): | 330 def psNodeAffiliationsSetCb(self): |
237 self.disp(_(u"affiliations have been set"), 1) | 331 self.disp(_(u"affiliations have been set"), 1) |
238 self.host.quit() | 332 self.host.quit() |
239 | 333 |
240 def psNodeAffiliationsSetEb(self, failure_): | 334 def psNodeAffiliationsSetEb(self, failure_): |
241 self.disp(u"can't set node affiliations: {reason}".format( | 335 self.disp( |
242 reason=failure_), error=True) | 336 u"can't set node affiliations: {reason}".format(reason=failure_), error=True |
337 ) | |
243 self.host.quit(C.EXIT_BRIDGE_ERRBACK) | 338 self.host.quit(C.EXIT_BRIDGE_ERRBACK) |
244 | 339 |
245 def start(self): | 340 def start(self): |
246 affiliations = dict(self.args.affiliations) | 341 affiliations = dict(self.args.affiliations) |
247 self.host.bridge.psNodeAffiliationsSet( | 342 self.host.bridge.psNodeAffiliationsSet( |
248 self.args.service, | 343 self.args.service, |
249 self.args.node, | 344 self.args.node, |
250 affiliations, | 345 affiliations, |
251 self.profile, | 346 self.profile, |
252 callback=self.psNodeAffiliationsSetCb, | 347 callback=self.psNodeAffiliationsSetCb, |
253 errback=self.psNodeAffiliationsSetEb) | 348 errback=self.psNodeAffiliationsSetEb, |
349 ) | |
254 | 350 |
255 | 351 |
256 class NodeAffiliations(base.CommandBase): | 352 class NodeAffiliations(base.CommandBase): |
257 subcommands = (NodeAffiliationsGet, NodeAffiliationsSet) | 353 subcommands = (NodeAffiliationsGet, NodeAffiliationsSet) |
258 | 354 |
259 def __init__(self, host): | 355 def __init__(self, host): |
260 super(NodeAffiliations, self).__init__(host, 'affiliations', use_profile=False, help=_(u'set or retrieve node affiliations')) | 356 super(NodeAffiliations, self).__init__( |
357 host, | |
358 "affiliations", | |
359 use_profile=False, | |
360 help=_(u"set or retrieve node affiliations"), | |
361 ) | |
261 | 362 |
262 | 363 |
263 class NodeSubscriptionsGet(base.CommandBase): | 364 class NodeSubscriptionsGet(base.CommandBase): |
264 | 365 def __init__(self, host): |
265 def __init__(self, host): | 366 base.CommandBase.__init__( |
266 base.CommandBase.__init__(self, host, 'get', use_output=C.OUTPUT_DICT, use_pubsub=True, pubsub_flags={C.NODE}, help=_(u'retrieve node subscriptions (for node owner)')) | 367 self, |
267 self.need_loop=True | 368 host, |
369 "get", | |
370 use_output=C.OUTPUT_DICT, | |
371 use_pubsub=True, | |
372 pubsub_flags={C.NODE}, | |
373 help=_(u"retrieve node subscriptions (for node owner)"), | |
374 ) | |
375 self.need_loop = True | |
268 | 376 |
269 def add_parser_options(self): | 377 def add_parser_options(self): |
270 pass | 378 pass |
271 | 379 |
272 def psNodeSubscriptionsGetCb(self, subscriptions): | 380 def psNodeSubscriptionsGetCb(self, subscriptions): |
273 self.output(subscriptions) | 381 self.output(subscriptions) |
274 self.host.quit() | 382 self.host.quit() |
275 | 383 |
276 def psNodeSubscriptionsGetEb(self, failure_): | 384 def psNodeSubscriptionsGetEb(self, failure_): |
277 self.disp(u"can't get node subscriptions: {reason}".format( | 385 self.disp( |
278 reason=failure_), error=True) | 386 u"can't get node subscriptions: {reason}".format(reason=failure_), error=True |
387 ) | |
279 self.host.quit(C.EXIT_BRIDGE_ERRBACK) | 388 self.host.quit(C.EXIT_BRIDGE_ERRBACK) |
280 | 389 |
281 def start(self): | 390 def start(self): |
282 self.host.bridge.psNodeSubscriptionsGet( | 391 self.host.bridge.psNodeSubscriptionsGet( |
283 self.args.service, | 392 self.args.service, |
284 self.args.node, | 393 self.args.node, |
285 self.profile, | 394 self.profile, |
286 callback=self.psNodeSubscriptionsGetCb, | 395 callback=self.psNodeSubscriptionsGetCb, |
287 errback=self.psNodeSubscriptionsGetEb) | 396 errback=self.psNodeSubscriptionsGetEb, |
397 ) | |
288 | 398 |
289 | 399 |
290 class StoreSubscriptionAction(argparse.Action): | 400 class StoreSubscriptionAction(argparse.Action): |
291 """Action which handle subscription parameter for owner | 401 """Action which handle subscription parameter for owner |
292 | 402 |
299 while values: | 409 while values: |
300 jid_s = values.pop(0) | 410 jid_s = values.pop(0) |
301 try: | 411 try: |
302 subscription = values.pop(0) | 412 subscription = values.pop(0) |
303 except IndexError: | 413 except IndexError: |
304 subscription = 'subscribed' | 414 subscription = "subscribed" |
305 if subscription not in ALLOWED_SUBSCRIPTIONS_OWNER: | 415 if subscription not in ALLOWED_SUBSCRIPTIONS_OWNER: |
306 parser.error(_(u"subscription must be one of {}").format(u', '.join(ALLOWED_SUBSCRIPTIONS_OWNER))) | 416 parser.error( |
417 _(u"subscription must be one of {}").format( | |
418 u", ".join(ALLOWED_SUBSCRIPTIONS_OWNER) | |
419 ) | |
420 ) | |
307 dest_dict[jid_s] = subscription | 421 dest_dict[jid_s] = subscription |
308 | 422 |
309 | 423 |
310 class NodeSubscriptionsSet(base.CommandBase): | 424 class NodeSubscriptionsSet(base.CommandBase): |
311 | 425 def __init__(self, host): |
312 def __init__(self, host): | 426 base.CommandBase.__init__( |
313 base.CommandBase.__init__(self, host, 'set', use_pubsub=True, pubsub_flags={C.NODE}, use_verbose=True, help=_(u'set/modify subscriptions (for node owner)')) | 427 self, |
314 self.need_loop=True | 428 host, |
429 "set", | |
430 use_pubsub=True, | |
431 pubsub_flags={C.NODE}, | |
432 use_verbose=True, | |
433 help=_(u"set/modify subscriptions (for node owner)"), | |
434 ) | |
435 self.need_loop = True | |
315 | 436 |
316 def add_parser_options(self): | 437 def add_parser_options(self): |
317 # XXX: we use optional argument syntax for a required one because list of list of 2 elements | 438 # XXX: we use optional argument syntax for a required one because list of list of 2 elements |
318 # (uses to construct dicts) don't work with positional arguments | 439 # (uses to construct dicts) don't work with positional arguments |
319 self.parser.add_argument("-S", | 440 self.parser.add_argument( |
320 "--subscription", | 441 "-S", |
321 dest="subscriptions", | 442 "--subscription", |
322 default={}, | 443 dest="subscriptions", |
323 nargs='+', | 444 default={}, |
324 metavar=('JID [SUSBSCRIPTION]'), | 445 nargs="+", |
325 required=True, | 446 metavar=("JID [SUSBSCRIPTION]"), |
326 type=base.unicode_decoder, | 447 required=True, |
327 action=StoreSubscriptionAction, | 448 type=base.unicode_decoder, |
328 help=_(u"entity/subscription couple(s)")) | 449 action=StoreSubscriptionAction, |
450 help=_(u"entity/subscription couple(s)"), | |
451 ) | |
329 | 452 |
330 def psNodeSubscriptionsSetCb(self): | 453 def psNodeSubscriptionsSetCb(self): |
331 self.disp(_(u"subscriptions have been set"), 1) | 454 self.disp(_(u"subscriptions have been set"), 1) |
332 self.host.quit() | 455 self.host.quit() |
333 | 456 |
334 def psNodeSubscriptionsSetEb(self, failure_): | 457 def psNodeSubscriptionsSetEb(self, failure_): |
335 self.disp(u"can't set node subscriptions: {reason}".format( | 458 self.disp( |
336 reason=failure_), error=True) | 459 u"can't set node subscriptions: {reason}".format(reason=failure_), error=True |
460 ) | |
337 self.host.quit(C.EXIT_BRIDGE_ERRBACK) | 461 self.host.quit(C.EXIT_BRIDGE_ERRBACK) |
338 | 462 |
339 def start(self): | 463 def start(self): |
340 self.host.bridge.psNodeSubscriptionsSet( | 464 self.host.bridge.psNodeSubscriptionsSet( |
341 self.args.service, | 465 self.args.service, |
342 self.args.node, | 466 self.args.node, |
343 self.args.subscriptions, | 467 self.args.subscriptions, |
344 self.profile, | 468 self.profile, |
345 callback=self.psNodeSubscriptionsSetCb, | 469 callback=self.psNodeSubscriptionsSetCb, |
346 errback=self.psNodeSubscriptionsSetEb) | 470 errback=self.psNodeSubscriptionsSetEb, |
471 ) | |
347 | 472 |
348 | 473 |
349 class NodeSubscriptions(base.CommandBase): | 474 class NodeSubscriptions(base.CommandBase): |
350 subcommands = (NodeSubscriptionsGet, NodeSubscriptionsSet) | 475 subcommands = (NodeSubscriptionsGet, NodeSubscriptionsSet) |
351 | 476 |
352 def __init__(self, host): | 477 def __init__(self, host): |
353 super(NodeSubscriptions, self).__init__(host, 'subscriptions', use_profile=False, help=_(u'get or modify node subscriptions')) | 478 super(NodeSubscriptions, self).__init__( |
479 host, | |
480 "subscriptions", | |
481 use_profile=False, | |
482 help=_(u"get or modify node subscriptions"), | |
483 ) | |
354 | 484 |
355 | 485 |
356 class NodeSchemaSet(base.CommandBase): | 486 class NodeSchemaSet(base.CommandBase): |
357 | 487 def __init__(self, host): |
358 def __init__(self, host): | 488 base.CommandBase.__init__( |
359 base.CommandBase.__init__(self, host, 'set', use_pubsub=True, pubsub_flags={C.NODE}, use_verbose=True, help=_(u'set/replace a schema')) | 489 self, |
360 self.need_loop = True | 490 host, |
361 | 491 "set", |
362 def add_parser_options(self): | 492 use_pubsub=True, |
363 self.parser.add_argument('schema', help=_(u"schema to set (must be XML)")) | 493 pubsub_flags={C.NODE}, |
494 use_verbose=True, | |
495 help=_(u"set/replace a schema"), | |
496 ) | |
497 self.need_loop = True | |
498 | |
499 def add_parser_options(self): | |
500 self.parser.add_argument("schema", help=_(u"schema to set (must be XML)")) | |
364 | 501 |
365 def psSchemaSetCb(self): | 502 def psSchemaSetCb(self): |
366 self.disp(_(u'schema has been set'), 1) | 503 self.disp(_(u"schema has been set"), 1) |
367 self.host.quit() | 504 self.host.quit() |
368 | 505 |
369 def start(self): | 506 def start(self): |
370 self.host.bridge.psSchemaSet( | 507 self.host.bridge.psSchemaSet( |
371 self.args.service, | 508 self.args.service, |
372 self.args.node, | 509 self.args.node, |
373 self.args.schema, | 510 self.args.schema, |
374 self.profile, | 511 self.profile, |
375 callback=self.psSchemaSetCb, | 512 callback=self.psSchemaSetCb, |
376 errback=partial(self.errback, | 513 errback=partial( |
377 msg=_(u"can't set schema: {}"), | 514 self.errback, |
378 exit_code=C.EXIT_BRIDGE_ERRBACK)) | 515 msg=_(u"can't set schema: {}"), |
516 exit_code=C.EXIT_BRIDGE_ERRBACK, | |
517 ), | |
518 ) | |
379 | 519 |
380 | 520 |
381 class NodeSchemaEdit(base.CommandBase, common.BaseEdit): | 521 class NodeSchemaEdit(base.CommandBase, common.BaseEdit): |
382 use_items=False | 522 use_items = False |
383 | 523 |
384 def __init__(self, host): | 524 def __init__(self, host): |
385 base.CommandBase.__init__(self, host, 'edit', use_pubsub=True, pubsub_flags={C.NODE}, use_draft=True, use_verbose=True, help=_(u'edit a schema')) | 525 base.CommandBase.__init__( |
526 self, | |
527 host, | |
528 "edit", | |
529 use_pubsub=True, | |
530 pubsub_flags={C.NODE}, | |
531 use_draft=True, | |
532 use_verbose=True, | |
533 help=_(u"edit a schema"), | |
534 ) | |
386 common.BaseEdit.__init__(self, self.host, PUBSUB_SCHEMA_TMP_DIR) | 535 common.BaseEdit.__init__(self, self.host, PUBSUB_SCHEMA_TMP_DIR) |
387 self.need_loop=True | 536 self.need_loop = True |
388 | 537 |
389 def add_parser_options(self): | 538 def add_parser_options(self): |
390 pass | 539 pass |
391 | 540 |
392 def psSchemaSetCb(self): | 541 def psSchemaSetCb(self): |
393 self.disp(_(u'schema has been set'), 1) | 542 self.disp(_(u"schema has been set"), 1) |
394 self.host.quit() | 543 self.host.quit() |
395 | 544 |
396 def publish(self, schema): | 545 def publish(self, schema): |
397 self.host.bridge.psSchemaSet( | 546 self.host.bridge.psSchemaSet( |
398 self.args.service, | 547 self.args.service, |
399 self.args.node, | 548 self.args.node, |
400 schema, | 549 schema, |
401 self.profile, | 550 self.profile, |
402 callback=self.psSchemaSetCb, | 551 callback=self.psSchemaSetCb, |
403 errback=partial(self.errback, | 552 errback=partial( |
404 msg=_(u"can't set schema: {}"), | 553 self.errback, |
405 exit_code=C.EXIT_BRIDGE_ERRBACK)) | 554 msg=_(u"can't set schema: {}"), |
555 exit_code=C.EXIT_BRIDGE_ERRBACK, | |
556 ), | |
557 ) | |
406 | 558 |
407 def psSchemaGetCb(self, schema): | 559 def psSchemaGetCb(self, schema): |
408 try: | 560 try: |
409 from lxml import etree | 561 from lxml import etree |
410 except ImportError: | 562 except ImportError: |
411 self.disp(u"lxml module must be installed to use edit, please install it with \"pip install lxml\"", error=True) | 563 self.disp( |
564 u'lxml module must be installed to use edit, please install it with "pip install lxml"', | |
565 error=True, | |
566 ) | |
412 self.host.quit(1) | 567 self.host.quit(1) |
413 content_file_obj, content_file_path = self.getTmpFile() | 568 content_file_obj, content_file_path = self.getTmpFile() |
414 schema = schema.strip() | 569 schema = schema.strip() |
415 if schema: | 570 if schema: |
416 parser = etree.XMLParser(remove_blank_text=True) | 571 parser = etree.XMLParser(remove_blank_text=True) |
417 schema_elt = etree.fromstring(schema, parser) | 572 schema_elt = etree.fromstring(schema, parser) |
418 content_file_obj.write(etree.tostring(schema_elt, encoding="utf-8", pretty_print=True)) | 573 content_file_obj.write( |
574 etree.tostring(schema_elt, encoding="utf-8", pretty_print=True) | |
575 ) | |
419 content_file_obj.seek(0) | 576 content_file_obj.seek(0) |
420 self.runEditor("pubsub_schema_editor_args", content_file_path, content_file_obj) | 577 self.runEditor("pubsub_schema_editor_args", content_file_path, content_file_obj) |
421 | 578 |
422 def start(self): | 579 def start(self): |
423 self.host.bridge.psSchemaGet( | 580 self.host.bridge.psSchemaGet( |
424 self.args.service, | 581 self.args.service, |
425 self.args.node, | 582 self.args.node, |
426 self.profile, | 583 self.profile, |
427 callback=self.psSchemaGetCb, | 584 callback=self.psSchemaGetCb, |
428 errback=partial(self.errback, | 585 errback=partial( |
429 msg=_(u"can't edit schema: {}"), | 586 self.errback, |
430 exit_code=C.EXIT_BRIDGE_ERRBACK)) | 587 msg=_(u"can't edit schema: {}"), |
588 exit_code=C.EXIT_BRIDGE_ERRBACK, | |
589 ), | |
590 ) | |
431 | 591 |
432 | 592 |
433 class NodeSchemaGet(base.CommandBase): | 593 class NodeSchemaGet(base.CommandBase): |
434 | 594 def __init__(self, host): |
435 def __init__(self, host): | 595 base.CommandBase.__init__( |
436 base.CommandBase.__init__(self, host, 'get', use_output=C.OUTPUT_XML, use_pubsub=True, pubsub_flags={C.NODE}, use_verbose=True, help=_(u'get schema')) | 596 self, |
437 self.need_loop=True | 597 host, |
598 "get", | |
599 use_output=C.OUTPUT_XML, | |
600 use_pubsub=True, | |
601 pubsub_flags={C.NODE}, | |
602 use_verbose=True, | |
603 help=_(u"get schema"), | |
604 ) | |
605 self.need_loop = True | |
438 | 606 |
439 def add_parser_options(self): | 607 def add_parser_options(self): |
440 pass | 608 pass |
441 | 609 |
442 def psSchemaGetCb(self, schema): | 610 def psSchemaGetCb(self, schema): |
443 if not schema: | 611 if not schema: |
444 self.disp(_(u'no schema found'), 1) | 612 self.disp(_(u"no schema found"), 1) |
445 self.host.quit(1) | 613 self.host.quit(1) |
446 self.output(schema) | 614 self.output(schema) |
447 self.host.quit() | 615 self.host.quit() |
448 | 616 |
449 def start(self): | 617 def start(self): |
450 self.host.bridge.psSchemaGet( | 618 self.host.bridge.psSchemaGet( |
451 self.args.service, | 619 self.args.service, |
452 self.args.node, | 620 self.args.node, |
453 self.profile, | 621 self.profile, |
454 callback=self.psSchemaGetCb, | 622 callback=self.psSchemaGetCb, |
455 errback=partial(self.errback, | 623 errback=partial( |
456 msg=_(u"can't get schema: {}"), | 624 self.errback, |
457 exit_code=C.EXIT_BRIDGE_ERRBACK)) | 625 msg=_(u"can't get schema: {}"), |
626 exit_code=C.EXIT_BRIDGE_ERRBACK, | |
627 ), | |
628 ) | |
458 | 629 |
459 | 630 |
460 class NodeSchema(base.CommandBase): | 631 class NodeSchema(base.CommandBase): |
461 subcommands = (NodeSchemaSet, NodeSchemaEdit, NodeSchemaGet) | 632 subcommands = (NodeSchemaSet, NodeSchemaEdit, NodeSchemaGet) |
462 | 633 |
463 def __init__(self, host): | 634 def __init__(self, host): |
464 super(NodeSchema, self).__init__(host, 'schema', use_profile=False, help=_(u"data schema manipulation")) | 635 super(NodeSchema, self).__init__( |
636 host, "schema", use_profile=False, help=_(u"data schema manipulation") | |
637 ) | |
465 | 638 |
466 | 639 |
467 class Node(base.CommandBase): | 640 class Node(base.CommandBase): |
468 subcommands = (NodeInfo, NodeCreate, NodeDelete, NodeSet, NodeAffiliations, NodeSubscriptions, NodeSchema) | 641 subcommands = ( |
469 | 642 NodeInfo, |
470 def __init__(self, host): | 643 NodeCreate, |
471 super(Node, self).__init__(host, 'node', use_profile=False, help=_('node handling')) | 644 NodeDelete, |
645 NodeSet, | |
646 NodeAffiliations, | |
647 NodeSubscriptions, | |
648 NodeSchema, | |
649 ) | |
650 | |
651 def __init__(self, host): | |
652 super(Node, self).__init__( | |
653 host, "node", use_profile=False, help=_("node handling") | |
654 ) | |
472 | 655 |
473 | 656 |
474 class Set(base.CommandBase): | 657 class Set(base.CommandBase): |
475 | 658 def __init__(self, host): |
476 def __init__(self, host): | 659 base.CommandBase.__init__( |
477 base.CommandBase.__init__(self, host, 'set', use_pubsub=True, pubsub_flags={C.NODE}, help=_(u'publish a new item or update an existing one')) | 660 self, |
478 self.need_loop=True | 661 host, |
479 | 662 "set", |
480 def add_parser_options(self): | 663 use_pubsub=True, |
481 self.parser.add_argument("item", type=base.unicode_decoder, nargs='?', default=u'', help=_(u"id, URL of the item to update, keyword, or nothing for new item")) | 664 pubsub_flags={C.NODE}, |
665 help=_(u"publish a new item or update an existing one"), | |
666 ) | |
667 self.need_loop = True | |
668 | |
669 def add_parser_options(self): | |
670 self.parser.add_argument( | |
671 "item", | |
672 type=base.unicode_decoder, | |
673 nargs="?", | |
674 default=u"", | |
675 help=_(u"id, URL of the item to update, keyword, or nothing for new item"), | |
676 ) | |
482 | 677 |
483 def psItemsSendCb(self, published_id): | 678 def psItemsSendCb(self, published_id): |
484 if published_id: | 679 if published_id: |
485 self.disp(u"Item published at {pub_id}".format(pub_id=published_id)) | 680 self.disp(u"Item published at {pub_id}".format(pub_id=published_id)) |
486 else: | 681 else: |
489 | 684 |
490 def start(self): | 685 def start(self): |
491 try: | 686 try: |
492 from lxml import etree | 687 from lxml import etree |
493 except ImportError: | 688 except ImportError: |
494 self.disp(u"lxml module must be installed to use edit, please install it with \"pip install lxml\"", error=True) | 689 self.disp( |
690 u'lxml module must be installed to use edit, please install it with "pip install lxml"', | |
691 error=True, | |
692 ) | |
495 self.host.quit(1) | 693 self.host.quit(1) |
496 try: | 694 try: |
497 element = etree.parse(sys.stdin).getroot() | 695 element = etree.parse(sys.stdin).getroot() |
498 except Exception as e: | 696 except Exception as e: |
499 self.parser.error(_(u"Can't parse the payload XML in input: {msg}").format(msg=e)) | 697 self.parser.error( |
500 if element.tag in ('item', '{http://jabber.org/protocol/pubsub}item'): | 698 _(u"Can't parse the payload XML in input: {msg}").format(msg=e) |
699 ) | |
700 if element.tag in ("item", "{http://jabber.org/protocol/pubsub}item"): | |
501 if len(element) > 1: | 701 if len(element) > 1: |
502 self.parser.error(_(u"<item> can only have one child element (the payload)")) | 702 self.parser.error( |
703 _(u"<item> can only have one child element (the payload)") | |
704 ) | |
503 element = element[0] | 705 element = element[0] |
504 payload = etree.tostring(element, encoding='unicode') | 706 payload = etree.tostring(element, encoding="unicode") |
505 | 707 |
506 self.host.bridge.psItemSend(self.args.service, | 708 self.host.bridge.psItemSend( |
507 self.args.node, | 709 self.args.service, |
508 payload, | 710 self.args.node, |
509 self.args.item, | 711 payload, |
510 {}, | 712 self.args.item, |
511 self.profile, | 713 {}, |
512 callback=self.psItemsSendCb, | 714 self.profile, |
513 errback=partial(self.errback, | 715 callback=self.psItemsSendCb, |
514 msg=_(u"can't send item: {}"), | 716 errback=partial( |
515 exit_code=C.EXIT_BRIDGE_ERRBACK)) | 717 self.errback, |
718 msg=_(u"can't send item: {}"), | |
719 exit_code=C.EXIT_BRIDGE_ERRBACK, | |
720 ), | |
721 ) | |
516 | 722 |
517 | 723 |
518 class Get(base.CommandBase): | 724 class Get(base.CommandBase): |
519 | 725 def __init__(self, host): |
520 def __init__(self, host): | 726 base.CommandBase.__init__( |
521 base.CommandBase.__init__(self, host, 'get', use_output=C.OUTPUT_LIST_XML, use_pubsub=True, pubsub_flags={C.NODE, C.MULTI_ITEMS}, help=_(u'get pubsub item(s)')) | 727 self, |
522 self.need_loop=True | 728 host, |
523 | 729 "get", |
524 def add_parser_options(self): | 730 use_output=C.OUTPUT_LIST_XML, |
525 self.parser.add_argument("-S", "--sub-id", type=base.unicode_decoder, default=u'', | 731 use_pubsub=True, |
526 help=_(u"subscription id")) | 732 pubsub_flags={C.NODE, C.MULTI_ITEMS}, |
527 # TODO: a key(s) argument to select keys to display | 733 help=_(u"get pubsub item(s)"), |
734 ) | |
735 self.need_loop = True | |
736 | |
737 def add_parser_options(self): | |
738 self.parser.add_argument( | |
739 "-S", | |
740 "--sub-id", | |
741 type=base.unicode_decoder, | |
742 default=u"", | |
743 help=_(u"subscription id"), | |
744 ) | |
745 # TODO: a key(s) argument to select keys to display | |
528 # TODO: add MAM filters | 746 # TODO: add MAM filters |
529 | |
530 | 747 |
531 def psItemsGetCb(self, ps_result): | 748 def psItemsGetCb(self, ps_result): |
532 self.output(ps_result[0]) | 749 self.output(ps_result[0]) |
533 self.host.quit(C.EXIT_OK) | 750 self.host.quit(C.EXIT_OK) |
534 | 751 |
535 def psItemsGetEb(self, failure_): | 752 def psItemsGetEb(self, failure_): |
536 self.disp(u"can't get pubsub items: {reason}".format( | 753 self.disp(u"can't get pubsub items: {reason}".format(reason=failure_), error=True) |
537 reason=failure_), error=True) | |
538 self.host.quit(C.EXIT_BRIDGE_ERRBACK) | 754 self.host.quit(C.EXIT_BRIDGE_ERRBACK) |
539 | 755 |
540 def start(self): | 756 def start(self): |
541 self.host.bridge.psItemsGet( | 757 self.host.bridge.psItemsGet( |
542 self.args.service, | 758 self.args.service, |
545 self.args.items, | 761 self.args.items, |
546 self.args.sub_id, | 762 self.args.sub_id, |
547 {}, | 763 {}, |
548 self.profile, | 764 self.profile, |
549 callback=self.psItemsGetCb, | 765 callback=self.psItemsGetCb, |
550 errback=self.psItemsGetEb) | 766 errback=self.psItemsGetEb, |
767 ) | |
768 | |
551 | 769 |
552 class Delete(base.CommandBase): | 770 class Delete(base.CommandBase): |
553 | 771 def __init__(self, host): |
554 def __init__(self, host): | 772 base.CommandBase.__init__( |
555 base.CommandBase.__init__(self, host, 'delete', use_pubsub=True, pubsub_flags={C.NODE, C.SINGLE_ITEM}, help=_(u'delete an item')) | 773 self, |
556 self.need_loop=True | 774 host, |
557 | 775 "delete", |
558 def add_parser_options(self): | 776 use_pubsub=True, |
559 self.parser.add_argument("-f", "--force", action='store_true', help=_(u"delete without confirmation")) | 777 pubsub_flags={C.NODE, C.SINGLE_ITEM}, |
560 self.parser.add_argument("-N", "--notify", action='store_true', help=_(u"notify deletion")) | 778 help=_(u"delete an item"), |
779 ) | |
780 self.need_loop = True | |
781 | |
782 def add_parser_options(self): | |
783 self.parser.add_argument( | |
784 "-f", "--force", action="store_true", help=_(u"delete without confirmation") | |
785 ) | |
786 self.parser.add_argument( | |
787 "-N", "--notify", action="store_true", help=_(u"notify deletion") | |
788 ) | |
561 | 789 |
562 def psItemsDeleteCb(self): | 790 def psItemsDeleteCb(self): |
563 self.disp(_(u'item {item_id} has been deleted').format(item_id=self.args.item)) | 791 self.disp(_(u"item {item_id} has been deleted").format(item_id=self.args.item)) |
564 self.host.quit(C.EXIT_OK) | 792 self.host.quit(C.EXIT_OK) |
565 | 793 |
566 def start(self): | 794 def start(self): |
567 if not self.args.item: | 795 if not self.args.item: |
568 self.parser.error(_(u"You need to specify an item to delete")) | 796 self.parser.error(_(u"You need to specify an item to delete")) |
569 if not self.args.force: | 797 if not self.args.force: |
570 message = _(u"Are you sure to delete item {item_id} ?").format(item_id=self.args.item) | 798 message = _(u"Are you sure to delete item {item_id} ?").format( |
799 item_id=self.args.item | |
800 ) | |
571 self.host.confirmOrQuit(message, _(u"item deletion cancelled")) | 801 self.host.confirmOrQuit(message, _(u"item deletion cancelled")) |
572 self.host.bridge.psRetractItem( | 802 self.host.bridge.psRetractItem( |
573 self.args.service, | 803 self.args.service, |
574 self.args.node, | 804 self.args.node, |
575 self.args.item, | 805 self.args.item, |
576 self.args.notify, | 806 self.args.notify, |
577 self.profile, | 807 self.profile, |
578 callback=self.psItemsDeleteCb, | 808 callback=self.psItemsDeleteCb, |
579 errback=partial(self.errback, | 809 errback=partial( |
580 msg=_(u"can't delete item: {}"), | 810 self.errback, |
581 exit_code=C.EXIT_BRIDGE_ERRBACK)) | 811 msg=_(u"can't delete item: {}"), |
812 exit_code=C.EXIT_BRIDGE_ERRBACK, | |
813 ), | |
814 ) | |
582 | 815 |
583 | 816 |
584 class Edit(base.CommandBase, common.BaseEdit): | 817 class Edit(base.CommandBase, common.BaseEdit): |
585 | 818 def __init__(self, host): |
586 def __init__(self, host): | 819 base.CommandBase.__init__( |
587 base.CommandBase.__init__(self, host, 'edit', use_verbose=True, use_pubsub=True, | 820 self, |
588 pubsub_flags={C.NODE, C.SINGLE_ITEM}, use_draft=True, help=_(u'edit an existing or new pubsub item')) | 821 host, |
822 "edit", | |
823 use_verbose=True, | |
824 use_pubsub=True, | |
825 pubsub_flags={C.NODE, C.SINGLE_ITEM}, | |
826 use_draft=True, | |
827 help=_(u"edit an existing or new pubsub item"), | |
828 ) | |
589 common.BaseEdit.__init__(self, self.host, PUBSUB_TMP_DIR) | 829 common.BaseEdit.__init__(self, self.host, PUBSUB_TMP_DIR) |
590 | 830 |
591 def add_parser_options(self): | 831 def add_parser_options(self): |
592 pass | 832 pass |
593 | 833 |
594 def edit(self, content_file_path, content_file_obj): | 834 def edit(self, content_file_path, content_file_obj): |
595 # we launch editor | 835 # we launch editor |
596 self.runEditor("pubsub_editor_args", content_file_path, content_file_obj) | 836 self.runEditor("pubsub_editor_args", content_file_path, content_file_obj) |
597 | 837 |
598 def publish(self, content): | 838 def publish(self, content): |
599 published_id = self.host.bridge.psItemSend(self.pubsub_service, self.pubsub_node, content, self.pubsub_item or '', {}, self.profile) | 839 published_id = self.host.bridge.psItemSend( |
840 self.pubsub_service, | |
841 self.pubsub_node, | |
842 content, | |
843 self.pubsub_item or "", | |
844 {}, | |
845 self.profile, | |
846 ) | |
600 if published_id: | 847 if published_id: |
601 self.disp(u"Item published at {pub_id}".format(pub_id=published_id)) | 848 self.disp(u"Item published at {pub_id}".format(pub_id=published_id)) |
602 else: | 849 else: |
603 self.disp(u"Item published") | 850 self.disp(u"Item published") |
604 | 851 |
605 def getItemData(self, service, node, item): | 852 def getItemData(self, service, node, item): |
606 try: | 853 try: |
607 from lxml import etree | 854 from lxml import etree |
608 except ImportError: | 855 except ImportError: |
609 self.disp(u"lxml module must be installed to use edit, please install it with \"pip install lxml\"", error=True) | 856 self.disp( |
857 u'lxml module must be installed to use edit, please install it with "pip install lxml"', | |
858 error=True, | |
859 ) | |
610 self.host.quit(1) | 860 self.host.quit(1) |
611 items = [item] if item is not None else [] | 861 items = [item] if item is not None else [] |
612 item_raw = self.host.bridge.psItemsGet(service, node, 1, items, "", {}, self.profile)[0][0] | 862 item_raw = self.host.bridge.psItemsGet( |
863 service, node, 1, items, "", {}, self.profile | |
864 )[0][0] | |
613 parser = etree.XMLParser(remove_blank_text=True) | 865 parser = etree.XMLParser(remove_blank_text=True) |
614 item_elt = etree.fromstring(item_raw, parser) | 866 item_elt = etree.fromstring(item_raw, parser) |
615 item_id = item_elt.get('id') | 867 item_id = item_elt.get("id") |
616 try: | 868 try: |
617 payload = item_elt[0] | 869 payload = item_elt[0] |
618 except IndexError: | 870 except IndexError: |
619 self.disp(_(u'Item has not payload'), 1) | 871 self.disp(_(u"Item has not payload"), 1) |
620 return u'' | 872 return u"" |
621 return etree.tostring(payload, encoding="unicode", pretty_print=True), item_id | 873 return etree.tostring(payload, encoding="unicode", pretty_print=True), item_id |
622 | 874 |
623 def start(self): | 875 def start(self): |
624 self.pubsub_service, self.pubsub_node, self.pubsub_item, content_file_path, content_file_obj = self.getItemPath() | 876 self.pubsub_service, self.pubsub_node, self.pubsub_item, content_file_path, content_file_obj = ( |
877 self.getItemPath() | |
878 ) | |
625 self.edit(content_file_path, content_file_obj) | 879 self.edit(content_file_path, content_file_obj) |
626 | 880 |
627 | 881 |
628 class Subscribe(base.CommandBase): | 882 class Subscribe(base.CommandBase): |
629 | 883 def __init__(self, host): |
630 def __init__(self, host): | 884 base.CommandBase.__init__( |
631 base.CommandBase.__init__(self, host, 'subscribe', use_pubsub=True, pubsub_flags={C.NODE}, use_verbose=True, help=_(u'subscribe to a node')) | 885 self, |
632 self.need_loop=True | 886 host, |
887 "subscribe", | |
888 use_pubsub=True, | |
889 pubsub_flags={C.NODE}, | |
890 use_verbose=True, | |
891 help=_(u"subscribe to a node"), | |
892 ) | |
893 self.need_loop = True | |
633 | 894 |
634 def add_parser_options(self): | 895 def add_parser_options(self): |
635 pass | 896 pass |
636 | 897 |
637 def psSubscribeCb(self, sub_id): | 898 def psSubscribeCb(self, sub_id): |
638 self.disp(_(u'subscription done'), 1) | 899 self.disp(_(u"subscription done"), 1) |
639 if sub_id: | 900 if sub_id: |
640 self.disp(_(u'subscription id: {sub_id}').format(sub_id=sub_id)) | 901 self.disp(_(u"subscription id: {sub_id}").format(sub_id=sub_id)) |
641 self.host.quit() | 902 self.host.quit() |
642 | 903 |
643 def start(self): | 904 def start(self): |
644 self.host.bridge.psSubscribe( | 905 self.host.bridge.psSubscribe( |
645 self.args.service, | 906 self.args.service, |
646 self.args.node, | 907 self.args.node, |
647 {}, | 908 {}, |
648 self.profile, | 909 self.profile, |
649 callback=self.psSubscribeCb, | 910 callback=self.psSubscribeCb, |
650 errback=partial(self.errback, | 911 errback=partial( |
651 msg=_(u"can't subscribe to node: {}"), | 912 self.errback, |
652 exit_code=C.EXIT_BRIDGE_ERRBACK)) | 913 msg=_(u"can't subscribe to node: {}"), |
914 exit_code=C.EXIT_BRIDGE_ERRBACK, | |
915 ), | |
916 ) | |
653 | 917 |
654 | 918 |
655 class Unsubscribe(base.CommandBase): | 919 class Unsubscribe(base.CommandBase): |
656 # TODO: voir pourquoi NodeNotFound sur subscribe juste après unsubscribe | 920 # TODO: voir pourquoi NodeNotFound sur subscribe juste après unsubscribe |
657 | 921 |
658 def __init__(self, host): | 922 def __init__(self, host): |
659 base.CommandBase.__init__(self, host, 'unsubscribe', use_pubsub=True, pubsub_flags={C.NODE}, use_verbose=True, help=_(u'unsubscribe from a node')) | 923 base.CommandBase.__init__( |
660 self.need_loop=True | 924 self, |
925 host, | |
926 "unsubscribe", | |
927 use_pubsub=True, | |
928 pubsub_flags={C.NODE}, | |
929 use_verbose=True, | |
930 help=_(u"unsubscribe from a node"), | |
931 ) | |
932 self.need_loop = True | |
661 | 933 |
662 def add_parser_options(self): | 934 def add_parser_options(self): |
663 pass | 935 pass |
664 | 936 |
665 def psUnsubscribeCb(self): | 937 def psUnsubscribeCb(self): |
666 self.disp(_(u'subscription removed'), 1) | 938 self.disp(_(u"subscription removed"), 1) |
667 self.host.quit() | 939 self.host.quit() |
668 | 940 |
669 def start(self): | 941 def start(self): |
670 self.host.bridge.psUnsubscribe( | 942 self.host.bridge.psUnsubscribe( |
671 self.args.service, | 943 self.args.service, |
672 self.args.node, | 944 self.args.node, |
673 self.profile, | 945 self.profile, |
674 callback=self.psUnsubscribeCb, | 946 callback=self.psUnsubscribeCb, |
675 errback=partial(self.errback, | 947 errback=partial( |
676 msg=_(u"can't unsubscribe from node: {}"), | 948 self.errback, |
677 exit_code=C.EXIT_BRIDGE_ERRBACK)) | 949 msg=_(u"can't unsubscribe from node: {}"), |
950 exit_code=C.EXIT_BRIDGE_ERRBACK, | |
951 ), | |
952 ) | |
678 | 953 |
679 | 954 |
680 class Subscriptions(base.CommandBase): | 955 class Subscriptions(base.CommandBase): |
681 | 956 def __init__(self, host): |
682 def __init__(self, host): | 957 base.CommandBase.__init__( |
683 base.CommandBase.__init__(self, host, 'subscriptions', use_output=C.OUTPUT_LIST_DICT, use_pubsub=True, help=_(u'retrieve all subscriptions on a service')) | 958 self, |
684 self.need_loop=True | 959 host, |
960 "subscriptions", | |
961 use_output=C.OUTPUT_LIST_DICT, | |
962 use_pubsub=True, | |
963 help=_(u"retrieve all subscriptions on a service"), | |
964 ) | |
965 self.need_loop = True | |
685 | 966 |
686 def add_parser_options(self): | 967 def add_parser_options(self): |
687 pass | 968 pass |
688 | 969 |
689 def psSubscriptionsGetCb(self, subscriptions): | 970 def psSubscriptionsGetCb(self, subscriptions): |
694 self.host.bridge.psSubscriptionsGet( | 975 self.host.bridge.psSubscriptionsGet( |
695 self.args.service, | 976 self.args.service, |
696 self.args.node, | 977 self.args.node, |
697 self.profile, | 978 self.profile, |
698 callback=self.psSubscriptionsGetCb, | 979 callback=self.psSubscriptionsGetCb, |
699 errback=partial(self.errback, | 980 errback=partial( |
700 msg=_(u"can't retrieve subscriptions: {}"), | 981 self.errback, |
701 exit_code=C.EXIT_BRIDGE_ERRBACK)) | 982 msg=_(u"can't retrieve subscriptions: {}"), |
983 exit_code=C.EXIT_BRIDGE_ERRBACK, | |
984 ), | |
985 ) | |
702 | 986 |
703 | 987 |
704 class Affiliations(base.CommandBase): | 988 class Affiliations(base.CommandBase): |
705 | 989 def __init__(self, host): |
706 def __init__(self, host): | 990 base.CommandBase.__init__( |
707 base.CommandBase.__init__(self, host, 'affiliations', use_output=C.OUTPUT_DICT, use_pubsub=True, help=_(u'retrieve all affiliations on a service')) | 991 self, |
708 self.need_loop=True | 992 host, |
993 "affiliations", | |
994 use_output=C.OUTPUT_DICT, | |
995 use_pubsub=True, | |
996 help=_(u"retrieve all affiliations on a service"), | |
997 ) | |
998 self.need_loop = True | |
709 | 999 |
710 def add_parser_options(self): | 1000 def add_parser_options(self): |
711 pass | 1001 pass |
712 | 1002 |
713 def psAffiliationsGetCb(self, affiliations): | 1003 def psAffiliationsGetCb(self, affiliations): |
714 self.output(affiliations) | 1004 self.output(affiliations) |
715 self.host.quit() | 1005 self.host.quit() |
716 | 1006 |
717 def psAffiliationsGetEb(self, failure_): | 1007 def psAffiliationsGetEb(self, failure_): |
718 self.disp(u"can't get node affiliations: {reason}".format( | 1008 self.disp( |
719 reason=failure_), error=True) | 1009 u"can't get node affiliations: {reason}".format(reason=failure_), error=True |
1010 ) | |
720 self.host.quit(C.EXIT_BRIDGE_ERRBACK) | 1011 self.host.quit(C.EXIT_BRIDGE_ERRBACK) |
721 | 1012 |
722 def start(self): | 1013 def start(self): |
723 self.host.bridge.psAffiliationsGet( | 1014 self.host.bridge.psAffiliationsGet( |
724 self.args.service, | 1015 self.args.service, |
725 self.args.node, | 1016 self.args.node, |
726 self.profile, | 1017 self.profile, |
727 callback=self.psAffiliationsGetCb, | 1018 callback=self.psAffiliationsGetCb, |
728 errback=self.psAffiliationsGetEb) | 1019 errback=self.psAffiliationsGetEb, |
1020 ) | |
729 | 1021 |
730 | 1022 |
731 class Search(base.CommandBase): | 1023 class Search(base.CommandBase): |
732 """this command to a search without using MAM, i.e. by checking every items if dound by itself, so it may be heavy in resources both for server and client""" | 1024 """this command to a search without using MAM, i.e. by checking every items if dound by itself, so it may be heavy in resources both for server and client""" |
1025 | |
733 RE_FLAGS = re.MULTILINE | re.UNICODE | 1026 RE_FLAGS = re.MULTILINE | re.UNICODE |
734 EXEC_ACTIONS = (u'exec', u'external') | 1027 EXEC_ACTIONS = (u"exec", u"external") |
735 | 1028 |
736 def __init__(self, host): | 1029 def __init__(self, host): |
737 base.CommandBase.__init__(self, host, 'search', use_output=C.OUTPUT_XML, use_pubsub=True, pubsub_flags={C.MULTI_ITEMS, C.NO_MAX}, | 1030 base.CommandBase.__init__( |
738 use_verbose=True, help=_(u'search items corresponding to filters')) | 1031 self, |
739 self.need_loop=True | 1032 host, |
1033 "search", | |
1034 use_output=C.OUTPUT_XML, | |
1035 use_pubsub=True, | |
1036 pubsub_flags={C.MULTI_ITEMS, C.NO_MAX}, | |
1037 use_verbose=True, | |
1038 help=_(u"search items corresponding to filters"), | |
1039 ) | |
1040 self.need_loop = True | |
740 | 1041 |
741 @property | 1042 @property |
742 def etree(self): | 1043 def etree(self): |
743 """load lxml.etree only if needed""" | 1044 """load lxml.etree only if needed""" |
744 if self._etree is None: | 1045 if self._etree is None: |
745 from lxml import etree | 1046 from lxml import etree |
1047 | |
746 self._etree = etree | 1048 self._etree = etree |
747 return self._etree | 1049 return self._etree |
748 | 1050 |
749 def filter_opt(self, value, type_): | 1051 def filter_opt(self, value, type_): |
750 value = base.unicode_decoder(value) | 1052 value = base.unicode_decoder(value) |
753 def filter_flag(self, value, type_): | 1055 def filter_flag(self, value, type_): |
754 value = C.bool(value) | 1056 value = C.bool(value) |
755 return (type_, value) | 1057 return (type_, value) |
756 | 1058 |
757 def add_parser_options(self): | 1059 def add_parser_options(self): |
758 self.parser.add_argument("-D", "--max-depth", type=int, default=0, help=_(u"maximum depth of recursion (will search linked nodes if > 0, default: 0)")) | 1060 self.parser.add_argument( |
759 self.parser.add_argument("-m", "--max", type=int, default=30, help=_(u"maximum number of items to get per node ({} to get all items, default: 30)".format(C.NO_LIMIT))) | 1061 "-D", |
760 self.parser.add_argument("-N", "--namespace", action='append', nargs=2, default=[], | 1062 "--max-depth", |
761 metavar="NAME NAMESPACE", help=_(u"namespace to use for xpath")) | 1063 type=int, |
1064 default=0, | |
1065 help=_( | |
1066 u"maximum depth of recursion (will search linked nodes if > 0, default: 0)" | |
1067 ), | |
1068 ) | |
1069 self.parser.add_argument( | |
1070 "-m", | |
1071 "--max", | |
1072 type=int, | |
1073 default=30, | |
1074 help=_( | |
1075 u"maximum number of items to get per node ({} to get all items, default: 30)".format( | |
1076 C.NO_LIMIT | |
1077 ) | |
1078 ), | |
1079 ) | |
1080 self.parser.add_argument( | |
1081 "-N", | |
1082 "--namespace", | |
1083 action="append", | |
1084 nargs=2, | |
1085 default=[], | |
1086 metavar="NAME NAMESPACE", | |
1087 help=_(u"namespace to use for xpath"), | |
1088 ) | |
762 | 1089 |
763 # filters | 1090 # filters |
764 filter_text = partial(self.filter_opt, type_=u'text') | 1091 filter_text = partial(self.filter_opt, type_=u"text") |
765 filter_re = partial(self.filter_opt, type_=u'regex') | 1092 filter_re = partial(self.filter_opt, type_=u"regex") |
766 filter_xpath = partial(self.filter_opt, type_=u'xpath') | 1093 filter_xpath = partial(self.filter_opt, type_=u"xpath") |
767 filter_python = partial(self.filter_opt, type_=u'python') | 1094 filter_python = partial(self.filter_opt, type_=u"python") |
768 filters = self.parser.add_argument_group(_(u'filters'), _(u'only items corresponding to following filters will be kept')) | 1095 filters = self.parser.add_argument_group( |
769 filters.add_argument("-t", "--text", | 1096 _(u"filters"), |
770 action='append', dest='filters', type=filter_text, | 1097 _(u"only items corresponding to following filters will be kept"), |
771 metavar='TEXT', | 1098 ) |
772 help=_(u"full text filter, item must contain this string (XML included)")) | 1099 filters.add_argument( |
773 filters.add_argument("-r", "--regex", | 1100 "-t", |
774 action='append', dest='filters', type=filter_re, | 1101 "--text", |
775 metavar='EXPRESSION', | 1102 action="append", |
776 help=_(u"like --text but using a regular expression")) | 1103 dest="filters", |
777 filters.add_argument("-x", "--xpath", | 1104 type=filter_text, |
778 action='append', dest='filters', type=filter_xpath, | 1105 metavar="TEXT", |
779 metavar='XPATH', | 1106 help=_(u"full text filter, item must contain this string (XML included)"), |
780 help=_(u"filter items which has elements matching this xpath")) | 1107 ) |
781 filters.add_argument("-P", "--python", | 1108 filters.add_argument( |
782 action='append', dest='filters', type=filter_python, | 1109 "-r", |
783 metavar='PYTHON_CODE', | 1110 "--regex", |
784 help=_(u'Python expression which much return a bool (True to keep item, False to reject it). "item" is raw text item, "item_xml" is lxml\'s etree.Element')) | 1111 action="append", |
1112 dest="filters", | |
1113 type=filter_re, | |
1114 metavar="EXPRESSION", | |
1115 help=_(u"like --text but using a regular expression"), | |
1116 ) | |
1117 filters.add_argument( | |
1118 "-x", | |
1119 "--xpath", | |
1120 action="append", | |
1121 dest="filters", | |
1122 type=filter_xpath, | |
1123 metavar="XPATH", | |
1124 help=_(u"filter items which has elements matching this xpath"), | |
1125 ) | |
1126 filters.add_argument( | |
1127 "-P", | |
1128 "--python", | |
1129 action="append", | |
1130 dest="filters", | |
1131 type=filter_python, | |
1132 metavar="PYTHON_CODE", | |
1133 help=_( | |
1134 u'Python expression which much return a bool (True to keep item, False to reject it). "item" is raw text item, "item_xml" is lxml\'s etree.Element' | |
1135 ), | |
1136 ) | |
785 | 1137 |
786 # filters flags | 1138 # filters flags |
787 flag_case = partial(self.filter_flag, type_=u'ignore-case') | 1139 flag_case = partial(self.filter_flag, type_=u"ignore-case") |
788 flag_invert = partial(self.filter_flag, type_=u'invert') | 1140 flag_invert = partial(self.filter_flag, type_=u"invert") |
789 flag_dotall = partial(self.filter_flag, type_=u'dotall') | 1141 flag_dotall = partial(self.filter_flag, type_=u"dotall") |
790 flag_matching = partial(self.filter_flag, type_=u'only-matching') | 1142 flag_matching = partial(self.filter_flag, type_=u"only-matching") |
791 flags = self.parser.add_argument_group(_(u'filters flags'), _(u'filters modifiers (change behaviour of following filters)')) | 1143 flags = self.parser.add_argument_group( |
792 flags.add_argument("-C", "--ignore-case", | 1144 _(u"filters flags"), |
793 action='append', dest='filters', type=flag_case, | 1145 _(u"filters modifiers (change behaviour of following filters)"), |
794 const=('ignore-case', True), nargs='?', | 1146 ) |
795 metavar='BOOLEAN', | 1147 flags.add_argument( |
796 help=_(u"(don't) ignore case in following filters (default: case sensitive)")) | 1148 "-C", |
797 flags.add_argument("-I", "--invert", | 1149 "--ignore-case", |
798 action='append', dest='filters', type=flag_invert, | 1150 action="append", |
799 const=('invert', True), nargs='?', | 1151 dest="filters", |
800 metavar='BOOLEAN', | 1152 type=flag_case, |
801 help=_(u"(don't) invert effect of following filters (default: don't invert)")) | 1153 const=("ignore-case", True), |
802 flags.add_argument("-A", "--dot-all", | 1154 nargs="?", |
803 action='append', dest='filters', type=flag_dotall, | 1155 metavar="BOOLEAN", |
804 const=('dotall', True), nargs='?', | 1156 help=_(u"(don't) ignore case in following filters (default: case sensitive)"), |
805 metavar='BOOLEAN', | 1157 ) |
806 help=_(u"(don't) use DOTALL option for regex (default: don't use)")) | 1158 flags.add_argument( |
807 flags.add_argument("-o", "--only-matching", | 1159 "-I", |
808 action='append', dest='filters', type=flag_matching, | 1160 "--invert", |
809 const=('only-matching', True), nargs='?', | 1161 action="append", |
810 metavar='BOOLEAN', | 1162 dest="filters", |
811 help=_(u"keep only the matching part of the item")) | 1163 type=flag_invert, |
1164 const=("invert", True), | |
1165 nargs="?", | |
1166 metavar="BOOLEAN", | |
1167 help=_(u"(don't) invert effect of following filters (default: don't invert)"), | |
1168 ) | |
1169 flags.add_argument( | |
1170 "-A", | |
1171 "--dot-all", | |
1172 action="append", | |
1173 dest="filters", | |
1174 type=flag_dotall, | |
1175 const=("dotall", True), | |
1176 nargs="?", | |
1177 metavar="BOOLEAN", | |
1178 help=_(u"(don't) use DOTALL option for regex (default: don't use)"), | |
1179 ) | |
1180 flags.add_argument( | |
1181 "-o", | |
1182 "--only-matching", | |
1183 action="append", | |
1184 dest="filters", | |
1185 type=flag_matching, | |
1186 const=("only-matching", True), | |
1187 nargs="?", | |
1188 metavar="BOOLEAN", | |
1189 help=_(u"keep only the matching part of the item"), | |
1190 ) | |
812 | 1191 |
813 # action | 1192 # action |
814 self.parser.add_argument("action", | 1193 self.parser.add_argument( |
815 default="print", | 1194 "action", |
816 nargs='?', | 1195 default="print", |
817 choices=('print', 'exec', 'external'), | 1196 nargs="?", |
818 help=_(u"action to do on found items (default: print)")) | 1197 choices=("print", "exec", "external"), |
1198 help=_(u"action to do on found items (default: print)"), | |
1199 ) | |
819 self.parser.add_argument("command", nargs=argparse.REMAINDER) | 1200 self.parser.add_argument("command", nargs=argparse.REMAINDER) |
820 | 1201 |
821 def psItemsGetEb(self, failure_, service, node): | 1202 def psItemsGetEb(self, failure_, service, node): |
822 self.disp(u"can't get pubsub items at {service} (node: {node}): {reason}".format( | 1203 self.disp( |
823 service=service, | 1204 u"can't get pubsub items at {service} (node: {node}): {reason}".format( |
824 node=node, | 1205 service=service, node=node, reason=failure_ |
825 reason=failure_), error=True) | 1206 ), |
1207 error=True, | |
1208 ) | |
826 self.to_get -= 1 | 1209 self.to_get -= 1 |
827 | 1210 |
828 def getItems(self, depth, service, node, items): | 1211 def getItems(self, depth, service, node, items): |
829 search = partial(self.search, depth=depth) | 1212 search = partial(self.search, depth=depth) |
830 errback = partial(self.psItemsGetEb, service=service, node=node) | 1213 errback = partial(self.psItemsGetEb, service=service, node=node) |
835 items, | 1218 items, |
836 "", | 1219 "", |
837 {}, | 1220 {}, |
838 self.profile, | 1221 self.profile, |
839 callback=search, | 1222 callback=search, |
840 errback=errback | 1223 errback=errback, |
841 ) | 1224 ) |
842 self.to_get += 1 | 1225 self.to_get += 1 |
843 | 1226 |
844 def _checkPubsubURL(self, match, found_nodes): | 1227 def _checkPubsubURL(self, match, found_nodes): |
845 """check that the matched URL is an xmpp: one | 1228 """check that the matched URL is an xmpp: one |
846 | 1229 |
847 @param found_nodes(list[unicode]): found_nodes | 1230 @param found_nodes(list[unicode]): found_nodes |
848 this list will be filled while xmpp: URIs are discovered | 1231 this list will be filled while xmpp: URIs are discovered |
849 """ | 1232 """ |
850 url = match.group(0) | 1233 url = match.group(0) |
851 if url.startswith(u'xmpp'): | 1234 if url.startswith(u"xmpp"): |
852 try: | 1235 try: |
853 url_data = uri.parseXMPPUri(url) | 1236 url_data = uri.parseXMPPUri(url) |
854 except ValueError: | 1237 except ValueError: |
855 return | 1238 return |
856 if url_data[u'type'] == u'pubsub': | 1239 if url_data[u"type"] == u"pubsub": |
857 found_node = {u'service': url_data[u'path'], | 1240 found_node = {u"service": url_data[u"path"], u"node": url_data[u"node"]} |
858 u'node': url_data[u'node']} | 1241 if u"item" in url_data: |
859 if u'item' in url_data: | 1242 found_node[u"item"] = url_data[u"item"] |
860 found_node[u'item'] = url_data[u'item'] | |
861 found_nodes.append(found_node) | 1243 found_nodes.append(found_node) |
862 | 1244 |
863 def getSubNodes(self, item, depth): | 1245 def getSubNodes(self, item, depth): |
864 """look for pubsub URIs in item, and getItems on the linked nodes""" | 1246 """look for pubsub URIs in item, and getItems on the linked nodes""" |
865 found_nodes = [] | 1247 found_nodes = [] |
866 checkURI = partial(self._checkPubsubURL, found_nodes=found_nodes) | 1248 checkURI = partial(self._checkPubsubURL, found_nodes=found_nodes) |
867 strings.RE_URL.sub(checkURI, item) | 1249 strings.RE_URL.sub(checkURI, item) |
868 for data in found_nodes: | 1250 for data in found_nodes: |
869 self.getItems(depth+1, | 1251 self.getItems( |
870 data[u'service'], | 1252 depth + 1, |
871 data[u'node'], | 1253 data[u"service"], |
872 [data[u'item']] if u'item' in data else [] | 1254 data[u"node"], |
873 ) | 1255 [data[u"item"]] if u"item" in data else [], |
1256 ) | |
874 | 1257 |
875 def parseXml(self, item): | 1258 def parseXml(self, item): |
876 try: | 1259 try: |
877 return self.etree.fromstring(item) | 1260 return self.etree.fromstring(item) |
878 except self.etree.XMLSyntaxError: | 1261 except self.etree.XMLSyntaxError: |
879 self.disp(_(u"item doesn't looks like XML, you have probably used --only-matching somewhere before and we have no more XML"), error=True) | 1262 self.disp( |
1263 _( | |
1264 u"item doesn't looks like XML, you have probably used --only-matching somewhere before and we have no more XML" | |
1265 ), | |
1266 error=True, | |
1267 ) | |
880 self.host.quit(C.EXIT_BAD_ARG) | 1268 self.host.quit(C.EXIT_BAD_ARG) |
881 | 1269 |
882 def filter(self, item): | 1270 def filter(self, item): |
883 """apply filters given on command line | 1271 """apply filters given on command line |
884 | 1272 |
895 for type_, value in self.args.filters: | 1283 for type_, value in self.args.filters: |
896 keep = True | 1284 keep = True |
897 | 1285 |
898 ## filters | 1286 ## filters |
899 | 1287 |
900 if type_ == u'text': | 1288 if type_ == u"text": |
901 if ignore_case: | 1289 if ignore_case: |
902 if value.lower() not in item.lower(): | 1290 if value.lower() not in item.lower(): |
903 keep = False | 1291 keep = False |
904 else: | 1292 else: |
905 if value not in item: | 1293 if value not in item: |
906 keep = False | 1294 keep = False |
907 if keep and only_matching: | 1295 if keep and only_matching: |
908 # doesn't really make sens to keep a fixed string | 1296 # doesn't really make sens to keep a fixed string |
909 # so we raise an error | 1297 # so we raise an error |
910 self.host.disp(_(u"--only-matching used with fixed --text string, are you sure?"), error=True) | 1298 self.host.disp( |
1299 _( | |
1300 u"--only-matching used with fixed --text string, are you sure?" | |
1301 ), | |
1302 error=True, | |
1303 ) | |
911 self.host.quit(C.EXIT_BAD_ARG) | 1304 self.host.quit(C.EXIT_BAD_ARG) |
912 elif type_ == u'regex': | 1305 elif type_ == u"regex": |
913 flags = self.RE_FLAGS | 1306 flags = self.RE_FLAGS |
914 if ignore_case: | 1307 if ignore_case: |
915 flags |= re.IGNORECASE | 1308 flags |= re.IGNORECASE |
916 if dotall: | 1309 if dotall: |
917 flags |= re.DOTALL | 1310 flags |= re.DOTALL |
918 match = re.search(value, item, flags) | 1311 match = re.search(value, item, flags) |
919 keep = match != None | 1312 keep = match != None |
920 if keep and only_matching: | 1313 if keep and only_matching: |
921 item = match.group() | 1314 item = match.group() |
922 item_xml = None | 1315 item_xml = None |
923 elif type_ == u'xpath': | 1316 elif type_ == u"xpath": |
924 if item_xml is None: | 1317 if item_xml is None: |
925 item_xml = self.parseXml(item) | 1318 item_xml = self.parseXml(item) |
926 try: | 1319 try: |
927 elts = item_xml.xpath(value, namespaces=self.args.namespace) | 1320 elts = item_xml.xpath(value, namespaces=self.args.namespace) |
928 except self.etree.XPathEvalError as e: | 1321 except self.etree.XPathEvalError as e: |
929 self.disp(_(u"can't use xpath: {reason}").format(reason=e), error=True) | 1322 self.disp( |
1323 _(u"can't use xpath: {reason}").format(reason=e), error=True | |
1324 ) | |
930 self.host.quit(C.EXIT_BAD_ARG) | 1325 self.host.quit(C.EXIT_BAD_ARG) |
931 keep = bool(elts) | 1326 keep = bool(elts) |
932 if keep and only_matching: | 1327 if keep and only_matching: |
933 item_xml = elts[0] | 1328 item_xml = elts[0] |
934 try: | 1329 try: |
935 item = self.etree.tostring(item_xml, encoding='unicode') | 1330 item = self.etree.tostring(item_xml, encoding="unicode") |
936 except TypeError: | 1331 except TypeError: |
937 # we have a string only, not an element | 1332 # we have a string only, not an element |
938 item = unicode(item_xml) | 1333 item = unicode(item_xml) |
939 item_xml = None | 1334 item_xml = None |
940 elif type_ == u'python': | 1335 elif type_ == u"python": |
941 if item_xml is None: | 1336 if item_xml is None: |
942 item_xml = self.parseXml(item) | 1337 item_xml = self.parseXml(item) |
943 cmd_ns = {u'item': item, | 1338 cmd_ns = {u"item": item, u"item_xml": item_xml} |
944 u'item_xml': item_xml | |
945 } | |
946 try: | 1339 try: |
947 keep = eval(value, cmd_ns) | 1340 keep = eval(value, cmd_ns) |
948 except SyntaxError as e: | 1341 except SyntaxError as e: |
949 self.disp(unicode(e), error=True) | 1342 self.disp(unicode(e), error=True) |
950 self.host.quit(C.EXIT_BAD_ARG) | 1343 self.host.quit(C.EXIT_BAD_ARG) |
951 | 1344 |
952 ## flags | 1345 ## flags |
953 | 1346 |
954 elif type_ == u'ignore-case': | 1347 elif type_ == u"ignore-case": |
955 ignore_case = value | 1348 ignore_case = value |
956 elif type_ == u'invert': | 1349 elif type_ == u"invert": |
957 invert = value | 1350 invert = value |
958 # we need to continue, else loop would end here | 1351 # we need to continue, else loop would end here |
959 continue | 1352 continue |
960 elif type_ == u'dotall': | 1353 elif type_ == u"dotall": |
961 dotall = value | 1354 dotall = value |
962 elif type_ == u'only-matching': | 1355 elif type_ == u"only-matching": |
963 only_matching = value | 1356 only_matching = value |
964 else: | 1357 else: |
965 raise exceptions.InternalError(_(u"unknown filter type {type}").format(type=type_)) | 1358 raise exceptions.InternalError( |
1359 _(u"unknown filter type {type}").format(type=type_) | |
1360 ) | |
966 | 1361 |
967 if invert: | 1362 if invert: |
968 keep = not keep | 1363 keep = not keep |
969 if not keep: | 1364 if not keep: |
970 return False, item | 1365 return False, item |
975 """called when item has been kepts and the action need to be done | 1370 """called when item has been kepts and the action need to be done |
976 | 1371 |
977 @param item(unicode): accepted item | 1372 @param item(unicode): accepted item |
978 """ | 1373 """ |
979 action = self.args.action | 1374 action = self.args.action |
980 if action == u'print' or self.host.verbosity > 0: | 1375 if action == u"print" or self.host.verbosity > 0: |
981 try: | 1376 try: |
982 self.output(item) | 1377 self.output(item) |
983 except self.etree.XMLSyntaxError: | 1378 except self.etree.XMLSyntaxError: |
984 # item is not valid XML, but a string | 1379 # item is not valid XML, but a string |
985 # can happen when --only-matching is used | 1380 # can happen when --only-matching is used |
986 self.disp(item) | 1381 self.disp(item) |
987 if action in self.EXEC_ACTIONS: | 1382 if action in self.EXEC_ACTIONS: |
988 item_elt = self.parseXml(item) | 1383 item_elt = self.parseXml(item) |
989 if action == u'exec': | 1384 if action == u"exec": |
990 use = {'service': metadata[u'service'], | 1385 use = { |
991 'node': metadata[u'node'], | 1386 "service": metadata[u"service"], |
992 'item': item_elt.get('id'), | 1387 "node": metadata[u"node"], |
993 'profile': self.profile | 1388 "item": item_elt.get("id"), |
994 } | 1389 "profile": self.profile, |
1390 } | |
995 # we need to send a copy of self.args.command | 1391 # we need to send a copy of self.args.command |
996 # else it would be modified | 1392 # else it would be modified |
997 parser_args, use_args = arg_tools.get_use_args(self.host, | 1393 parser_args, use_args = arg_tools.get_use_args( |
998 self.args.command, | 1394 self.host, self.args.command, use, verbose=self.host.verbosity > 1 |
999 use, | 1395 ) |
1000 verbose=self.host.verbosity > 1 | |
1001 ) | |
1002 cmd_args = sys.argv[0:1] + parser_args + use_args | 1396 cmd_args = sys.argv[0:1] + parser_args + use_args |
1003 else: | 1397 else: |
1004 cmd_args = self.args.command | 1398 cmd_args = self.args.command |
1005 | 1399 |
1006 | 1400 self.disp( |
1007 self.disp(u'COMMAND: {command}'.format( | 1401 u"COMMAND: {command}".format( |
1008 command = u' '.join([arg_tools.escape(a) for a in cmd_args])), 2) | 1402 command=u" ".join([arg_tools.escape(a) for a in cmd_args]) |
1009 if action == u'exec': | 1403 ), |
1404 2, | |
1405 ) | |
1406 if action == u"exec": | |
1010 ret = subprocess.call(cmd_args) | 1407 ret = subprocess.call(cmd_args) |
1011 else: | 1408 else: |
1012 p = subprocess.Popen(cmd_args, stdin=subprocess.PIPE) | 1409 p = subprocess.Popen(cmd_args, stdin=subprocess.PIPE) |
1013 p.communicate(item.encode('utf-8')) | 1410 p.communicate(item.encode("utf-8")) |
1014 ret = p.wait() | 1411 ret = p.wait() |
1015 if ret != 0: | 1412 if ret != 0: |
1016 self.disp(A.color(C.A_FAILURE, _(u"executed command failed with exit code {code}").format(code=ret))) | 1413 self.disp( |
1414 A.color( | |
1415 C.A_FAILURE, | |
1416 _(u"executed command failed with exit code {code}").format( | |
1417 code=ret | |
1418 ), | |
1419 ) | |
1420 ) | |
1017 | 1421 |
1018 def search(self, items_data, depth): | 1422 def search(self, items_data, depth): |
1019 """callback of getItems | 1423 """callback of getItems |
1020 | 1424 |
1021 this method filters items, get sub nodes if needed, | 1425 this method filters items, get sub nodes if needed, |
1031 keep, item = self.filter(item) | 1435 keep, item = self.filter(item) |
1032 if not keep: | 1436 if not keep: |
1033 continue | 1437 continue |
1034 self.doItemAction(item, metadata) | 1438 self.doItemAction(item, metadata) |
1035 | 1439 |
1036 # we check if we got all getItems results | 1440 # we check if we got all getItems results |
1037 self.to_get -= 1 | 1441 self.to_get -= 1 |
1038 if self.to_get == 0: | 1442 if self.to_get == 0: |
1039 # yes, we can quit | 1443 # yes, we can quit |
1040 self.host.quit() | 1444 self.host.quit() |
1041 assert self.to_get > 0 | 1445 assert self.to_get > 0 |
1042 | 1446 |
1043 def start(self): | 1447 def start(self): |
1044 if self.args.command: | 1448 if self.args.command: |
1045 if self.args.action not in self.EXEC_ACTIONS: | 1449 if self.args.action not in self.EXEC_ACTIONS: |
1046 self.parser.error(_(u"Command can only be used with {actions} actions").format( | 1450 self.parser.error( |
1047 actions=u', '.join(self.EXEC_ACTIONS))) | 1451 _(u"Command can only be used with {actions} actions").format( |
1452 actions=u", ".join(self.EXEC_ACTIONS) | |
1453 ) | |
1454 ) | |
1048 else: | 1455 else: |
1049 if self.args.action in self.EXEC_ACTIONS: | 1456 if self.args.action in self.EXEC_ACTIONS: |
1050 self.parser.error(_(u"you need to specify a command to execute")) | 1457 self.parser.error(_(u"you need to specify a command to execute")) |
1051 if not self.args.node: | 1458 if not self.args.node: |
1052 # TODO: handle get service affiliations when node is not set | 1459 # TODO: handle get service affiliations when node is not set |
1055 # when it reach 0 again, the command is finished | 1462 # when it reach 0 again, the command is finished |
1056 self.to_get = 0 | 1463 self.to_get = 0 |
1057 self._etree = None | 1464 self._etree = None |
1058 if self.args.filters is None: | 1465 if self.args.filters is None: |
1059 self.args.filters = [] | 1466 self.args.filters = [] |
1060 self.args.namespace = dict(self.args.namespace + [('pubsub', "http://jabber.org/protocol/pubsub")]) | 1467 self.args.namespace = dict( |
1468 self.args.namespace + [("pubsub", "http://jabber.org/protocol/pubsub")] | |
1469 ) | |
1061 self.getItems(0, self.args.service, self.args.node, self.args.items) | 1470 self.getItems(0, self.args.service, self.args.node, self.args.items) |
1062 | 1471 |
1063 | 1472 |
1064 class Uri(base.CommandBase): | 1473 class Uri(base.CommandBase): |
1065 | 1474 def __init__(self, host): |
1066 def __init__(self, host): | 1475 base.CommandBase.__init__( |
1067 base.CommandBase.__init__(self, host, 'uri', use_profile=False, use_pubsub=True, pubsub_flags={C.NODE, C.SINGLE_ITEM}, help=_(u'build URI')) | 1476 self, |
1068 self.need_loop=True | 1477 host, |
1069 | 1478 "uri", |
1070 def add_parser_options(self): | 1479 use_profile=False, |
1071 self.parser.add_argument("-p", "--profile", type=base.unicode_decoder, default=C.PROF_KEY_DEFAULT, help=_(u"profile (used when no server is specified)")) | 1480 use_pubsub=True, |
1481 pubsub_flags={C.NODE, C.SINGLE_ITEM}, | |
1482 help=_(u"build URI"), | |
1483 ) | |
1484 self.need_loop = True | |
1485 | |
1486 def add_parser_options(self): | |
1487 self.parser.add_argument( | |
1488 "-p", | |
1489 "--profile", | |
1490 type=base.unicode_decoder, | |
1491 default=C.PROF_KEY_DEFAULT, | |
1492 help=_(u"profile (used when no server is specified)"), | |
1493 ) | |
1072 | 1494 |
1073 def display_uri(self, jid_): | 1495 def display_uri(self, jid_): |
1074 uri_args = {} | 1496 uri_args = {} |
1075 if not self.args.service: | 1497 if not self.args.service: |
1076 self.args.service = jid.JID(jid_).bare | 1498 self.args.service = jid.JID(jid_).bare |
1077 | 1499 |
1078 for key in ('node', 'service', 'item'): | 1500 for key in ("node", "service", "item"): |
1079 value = getattr(self.args, key) | 1501 value = getattr(self.args, key) |
1080 if key == 'service': | 1502 if key == "service": |
1081 key = 'path' | 1503 key = "path" |
1082 if value: | 1504 if value: |
1083 uri_args[key] = value | 1505 uri_args[key] = value |
1084 self.disp(uri.buildXMPPUri(u'pubsub', **uri_args)) | 1506 self.disp(uri.buildXMPPUri(u"pubsub", **uri_args)) |
1085 self.host.quit() | 1507 self.host.quit() |
1086 | 1508 |
1087 def start(self): | 1509 def start(self): |
1088 if not self.args.service: | 1510 if not self.args.service: |
1089 self.host.bridge.asyncGetParamA( | 1511 self.host.bridge.asyncGetParamA( |
1090 u'JabberID', | 1512 u"JabberID", |
1091 u'Connection', | 1513 u"Connection", |
1092 profile_key=self.args.profile, | 1514 profile_key=self.args.profile, |
1093 callback=self.display_uri, | 1515 callback=self.display_uri, |
1094 errback=partial(self.errback, | 1516 errback=partial( |
1095 msg=_(u"can't retrieve jid: {}"), | 1517 self.errback, |
1096 exit_code=C.EXIT_BRIDGE_ERRBACK)) | 1518 msg=_(u"can't retrieve jid: {}"), |
1519 exit_code=C.EXIT_BRIDGE_ERRBACK, | |
1520 ), | |
1521 ) | |
1097 else: | 1522 else: |
1098 self.display_uri(None) | 1523 self.display_uri(None) |
1099 | 1524 |
1100 | 1525 |
1101 class HookCreate(base.CommandBase): | 1526 class HookCreate(base.CommandBase): |
1102 | 1527 def __init__(self, host): |
1103 def __init__(self, host): | 1528 base.CommandBase.__init__( |
1104 base.CommandBase.__init__(self, host, 'create', use_pubsub=True, pubsub_flags={C.NODE}, help=_(u'create a Pubsub hook')) | 1529 self, |
1105 self.need_loop=True | 1530 host, |
1106 | 1531 "create", |
1107 def add_parser_options(self): | 1532 use_pubsub=True, |
1108 self.parser.add_argument('-t', '--type', default=u'python', choices=('python', 'python_file', 'python_code'), help=_(u"hook type")) | 1533 pubsub_flags={C.NODE}, |
1109 self.parser.add_argument('-P', '--persistent', action='store_true', help=_(u"make hook persistent across restarts")) | 1534 help=_(u"create a Pubsub hook"), |
1110 self.parser.add_argument("hook_arg", type=base.unicode_decoder, help=_(u"argument of the hook (depend of the type)")) | 1535 ) |
1536 self.need_loop = True | |
1537 | |
1538 def add_parser_options(self): | |
1539 self.parser.add_argument( | |
1540 "-t", | |
1541 "--type", | |
1542 default=u"python", | |
1543 choices=("python", "python_file", "python_code"), | |
1544 help=_(u"hook type"), | |
1545 ) | |
1546 self.parser.add_argument( | |
1547 "-P", | |
1548 "--persistent", | |
1549 action="store_true", | |
1550 help=_(u"make hook persistent across restarts"), | |
1551 ) | |
1552 self.parser.add_argument( | |
1553 "hook_arg", | |
1554 type=base.unicode_decoder, | |
1555 help=_(u"argument of the hook (depend of the type)"), | |
1556 ) | |
1111 | 1557 |
1112 @staticmethod | 1558 @staticmethod |
1113 def checkArgs(self): | 1559 def checkArgs(self): |
1114 if self.args.type == u'python_file': | 1560 if self.args.type == u"python_file": |
1115 self.args.hook_arg = os.path.abspath(self.args.hook_arg) | 1561 self.args.hook_arg = os.path.abspath(self.args.hook_arg) |
1116 if not os.path.isfile(self.args.hook_arg): | 1562 if not os.path.isfile(self.args.hook_arg): |
1117 self.parser.error(_(u"{path} is not a file").format(path=self.args.hook_arg)) | 1563 self.parser.error( |
1564 _(u"{path} is not a file").format(path=self.args.hook_arg) | |
1565 ) | |
1118 | 1566 |
1119 def start(self): | 1567 def start(self): |
1120 self.checkArgs(self) | 1568 self.checkArgs(self) |
1121 self.host.bridge.psHookAdd( | 1569 self.host.bridge.psHookAdd( |
1122 self.args.service, | 1570 self.args.service, |
1124 self.args.type, | 1572 self.args.type, |
1125 self.args.hook_arg, | 1573 self.args.hook_arg, |
1126 self.args.persistent, | 1574 self.args.persistent, |
1127 self.profile, | 1575 self.profile, |
1128 callback=self.host.quit, | 1576 callback=self.host.quit, |
1129 errback=partial(self.errback, | 1577 errback=partial( |
1130 msg=_(u"can't create hook: {}"), | 1578 self.errback, |
1131 exit_code=C.EXIT_BRIDGE_ERRBACK)) | 1579 msg=_(u"can't create hook: {}"), |
1580 exit_code=C.EXIT_BRIDGE_ERRBACK, | |
1581 ), | |
1582 ) | |
1132 | 1583 |
1133 | 1584 |
1134 class HookDelete(base.CommandBase): | 1585 class HookDelete(base.CommandBase): |
1135 | 1586 def __init__(self, host): |
1136 def __init__(self, host): | 1587 base.CommandBase.__init__( |
1137 base.CommandBase.__init__(self, host, 'delete', use_pubsub=True, pubsub_flags={C.NODE}, help=_(u'delete a Pubsub hook')) | 1588 self, |
1138 self.need_loop=True | 1589 host, |
1139 | 1590 "delete", |
1140 def add_parser_options(self): | 1591 use_pubsub=True, |
1141 self.parser.add_argument('-t', '--type', default=u'', choices=('', 'python', 'python_file', 'python_code'), help=_(u"hook type to remove, empty to remove all (default: remove all)")) | 1592 pubsub_flags={C.NODE}, |
1142 self.parser.add_argument('-a', '--arg', dest='hook_arg', type=base.unicode_decoder, default=u'', help=_(u"argument of the hook to remove, empty to remove all (default: remove all)")) | 1593 help=_(u"delete a Pubsub hook"), |
1594 ) | |
1595 self.need_loop = True | |
1596 | |
1597 def add_parser_options(self): | |
1598 self.parser.add_argument( | |
1599 "-t", | |
1600 "--type", | |
1601 default=u"", | |
1602 choices=("", "python", "python_file", "python_code"), | |
1603 help=_(u"hook type to remove, empty to remove all (default: remove all)"), | |
1604 ) | |
1605 self.parser.add_argument( | |
1606 "-a", | |
1607 "--arg", | |
1608 dest="hook_arg", | |
1609 type=base.unicode_decoder, | |
1610 default=u"", | |
1611 help=_( | |
1612 u"argument of the hook to remove, empty to remove all (default: remove all)" | |
1613 ), | |
1614 ) | |
1143 | 1615 |
1144 def psHookRemoveCb(self, nb_deleted): | 1616 def psHookRemoveCb(self, nb_deleted): |
1145 self.disp(_(u'{nb_deleted} hook(s) have been deleted').format( | 1617 self.disp( |
1146 nb_deleted = nb_deleted)) | 1618 _(u"{nb_deleted} hook(s) have been deleted").format(nb_deleted=nb_deleted) |
1619 ) | |
1147 self.host.quit() | 1620 self.host.quit() |
1148 | 1621 |
1149 def start(self): | 1622 def start(self): |
1150 HookCreate.checkArgs(self) | 1623 HookCreate.checkArgs(self) |
1151 self.host.bridge.psHookRemove( | 1624 self.host.bridge.psHookRemove( |
1153 self.args.node, | 1626 self.args.node, |
1154 self.args.type, | 1627 self.args.type, |
1155 self.args.hook_arg, | 1628 self.args.hook_arg, |
1156 self.profile, | 1629 self.profile, |
1157 callback=self.psHookRemoveCb, | 1630 callback=self.psHookRemoveCb, |
1158 errback=partial(self.errback, | 1631 errback=partial( |
1159 msg=_(u"can't delete hook: {}"), | 1632 self.errback, |
1160 exit_code=C.EXIT_BRIDGE_ERRBACK)) | 1633 msg=_(u"can't delete hook: {}"), |
1634 exit_code=C.EXIT_BRIDGE_ERRBACK, | |
1635 ), | |
1636 ) | |
1161 | 1637 |
1162 | 1638 |
1163 class HookList(base.CommandBase): | 1639 class HookList(base.CommandBase): |
1164 | 1640 def __init__(self, host): |
1165 def __init__(self, host): | 1641 base.CommandBase.__init__( |
1166 base.CommandBase.__init__(self, host, 'list', use_output=C.OUTPUT_LIST_DICT, help=_(u'list hooks of a profile')) | 1642 self, |
1643 host, | |
1644 "list", | |
1645 use_output=C.OUTPUT_LIST_DICT, | |
1646 help=_(u"list hooks of a profile"), | |
1647 ) | |
1167 self.need_loop = True | 1648 self.need_loop = True |
1168 | 1649 |
1169 def add_parser_options(self): | 1650 def add_parser_options(self): |
1170 pass | 1651 pass |
1171 | 1652 |
1172 def psHookListCb(self, data): | 1653 def psHookListCb(self, data): |
1173 if not data: | 1654 if not data: |
1174 self.disp(_(u'No hook found.')) | 1655 self.disp(_(u"No hook found.")) |
1175 self.output(data) | 1656 self.output(data) |
1176 self.host.quit() | 1657 self.host.quit() |
1177 | 1658 |
1178 def start(self): | 1659 def start(self): |
1179 self.host.bridge.psHookList( | 1660 self.host.bridge.psHookList( |
1180 self.profile, | 1661 self.profile, |
1181 callback=self.psHookListCb, | 1662 callback=self.psHookListCb, |
1182 errback=partial(self.errback, | 1663 errback=partial( |
1183 msg=_(u"can't list hooks: {}"), | 1664 self.errback, |
1184 exit_code=C.EXIT_BRIDGE_ERRBACK)) | 1665 msg=_(u"can't list hooks: {}"), |
1666 exit_code=C.EXIT_BRIDGE_ERRBACK, | |
1667 ), | |
1668 ) | |
1185 | 1669 |
1186 | 1670 |
1187 class Hook(base.CommandBase): | 1671 class Hook(base.CommandBase): |
1188 subcommands = (HookCreate, HookDelete, HookList) | 1672 subcommands = (HookCreate, HookDelete, HookList) |
1189 | 1673 |
1190 def __init__(self, host): | 1674 def __init__(self, host): |
1191 super(Hook, self).__init__(host, 'hook', use_profile=False, use_verbose=True, help=_('trigger action on Pubsub notifications')) | 1675 super(Hook, self).__init__( |
1676 host, | |
1677 "hook", | |
1678 use_profile=False, | |
1679 use_verbose=True, | |
1680 help=_("trigger action on Pubsub notifications"), | |
1681 ) | |
1192 | 1682 |
1193 | 1683 |
1194 class Pubsub(base.CommandBase): | 1684 class Pubsub(base.CommandBase): |
1195 subcommands = (Set, Get, Delete, Edit, Subscribe, Unsubscribe, Subscriptions, Node, Affiliations, Search, Hook, Uri) | 1685 subcommands = ( |
1196 | 1686 Set, |
1197 def __init__(self, host): | 1687 Get, |
1198 super(Pubsub, self).__init__(host, 'pubsub', use_profile=False, help=_('PubSub nodes/items management')) | 1688 Delete, |
1689 Edit, | |
1690 Subscribe, | |
1691 Unsubscribe, | |
1692 Subscriptions, | |
1693 Node, | |
1694 Affiliations, | |
1695 Search, | |
1696 Hook, | |
1697 Uri, | |
1698 ) | |
1699 | |
1700 def __init__(self, host): | |
1701 super(Pubsub, self).__init__( | |
1702 host, "pubsub", use_profile=False, help=_("PubSub nodes/items management") | |
1703 ) |