Mercurial > libervia-backend
comparison frontends/src/jp/cmd_blog.py @ 1925:53b51866747f
jp (blog/edit): HTTP(S) and XMPP URLs can now be directly used in blog/edit command
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 24 Mar 2016 18:38:04 +0100 |
parents | 70b1a29e1338 |
children | 55a7328fafb6 |
comparison
equal
deleted
inserted
replaced
1924:70b1a29e1338 | 1925:53b51866747f |
---|---|
247 unicode_dump = json.dumps(mb_data, ensure_ascii=False, indent=4, separators=(',', ': '), sort_keys=True) | 247 unicode_dump = json.dumps(mb_data, ensure_ascii=False, indent=4, separators=(',', ': '), sort_keys=True) |
248 f.write(unicode_dump.encode('utf-8')) | 248 f.write(unicode_dump.encode('utf-8')) |
249 | 249 |
250 return mb_data, meta_file_path | 250 return mb_data, meta_file_path |
251 | 251 |
252 def edit(self, sat_conf, content_file_path, content_file_obj, mb_data=None): | 252 def edit(self, sat_conf, content_file_path, content_file_obj, |
253 pubsub_service, pubsub_node, mb_data=None): | |
253 """Edit the file contening the content using editor, and publish it""" | 254 """Edit the file contening the content using editor, and publish it""" |
254 item_ori_mb_data = mb_data | 255 item_ori_mb_data = mb_data |
255 # we first create metadata file | 256 # we first create metadata file |
256 meta_ori, meta_file_path = self.buildMetadataFile(content_file_path, item_ori_mb_data) | 257 meta_ori, meta_file_path = self.buildMetadataFile(content_file_path, item_ori_mb_data) |
257 | 258 |
327 | 328 |
328 if item_ori_mb_data is not None: | 329 if item_ori_mb_data is not None: |
329 mb_data['id'] = item_ori_mb_data['id'] | 330 mb_data['id'] = item_ori_mb_data['id'] |
330 | 331 |
331 try: | 332 try: |
332 self.host.bridge.mbSend('', '', mb_data, self.profile) | 333 self.host.bridge.mbSend(pubsub_service, pubsub_node, mb_data, self.profile) |
333 except Exception as e: | 334 except Exception as e: |
334 self.disp(u"Error while sending your blog, the temporary files have been kept at {content_path} and {meta_path}: {reason}".format( | 335 self.disp(u"Error while sending your blog, the temporary files have been kept at {content_path} and {meta_path}: {reason}".format( |
335 content_path=content_file_path, meta_path=meta_file_path, reason=e), error=True) | 336 content_path=content_file_path, meta_path=meta_file_path, reason=e), error=True) |
336 self.host.quit(1) | 337 self.host.quit(1) |
337 else: | 338 else: |
339 | 340 |
340 self.secureUnlink(sat_conf, content_file_path) | 341 self.secureUnlink(sat_conf, content_file_path) |
341 self.secureUnlink(sat_conf, meta_file_path) | 342 self.secureUnlink(sat_conf, meta_file_path) |
342 | 343 |
343 def start(self): | 344 def start(self): |
344 item_lower = self.args.item.lower() | 345 command = self.args.item.lower() |
345 sat_conf = config.parseMainConf() | 346 sat_conf = config.parseMainConf() |
346 # if there are user defined extension, we use them | 347 # if there are user defined extension, we use them |
347 SYNTAX_EXT.update(config.getConfig(sat_conf, 'jp', CONF_SYNTAX_EXT, {})) | 348 SYNTAX_EXT.update(config.getConfig(sat_conf, 'jp', CONF_SYNTAX_EXT, {})) |
348 current_syntax = None | 349 current_syntax = None |
349 | 350 pubsub_service = pubsub_node = '' |
350 if item_lower in ('new', 'last'): | 351 pubsub_item = None |
352 | |
353 if command not in ('new', 'last', 'current'): | |
354 # we have probably an URL, we try to parse it | |
355 import urlparse | |
356 url = self.args.item | |
357 parsed_url = urlparse.urlsplit(url) | |
358 if parsed_url.scheme.startswith('http'): | |
359 self.disp(u"{} URL found, trying to find associated xmpp: URI".format(parsed_url.scheme.upper()),1) | |
360 # HTTP URL, we try to find xmpp: links | |
361 try: | |
362 from lxml import etree | |
363 except ImportError: | |
364 self.disp(u"lxml module must be installed to use http(s) scheme, please install it with \"pip install lxml\"", error=True) | |
365 self.host.quit(1) | |
366 parser = etree.HTMLParser() | |
367 root = etree.parse(url, parser) | |
368 links = root.xpath("//link[@rel='alternate' and starts-with(@href, 'xmpp:')]") | |
369 if not links: | |
370 self.disp(u'Could not find alternate "xmpp:" URI, can\'t find associated XMPP PubSub node/item', error=True) | |
371 self.host.quit(1) | |
372 url = links[0].get('href') | |
373 parsed_url = urlparse.urlsplit(url) | |
374 | |
375 if parsed_url.scheme == 'xmpp': | |
376 self.disp(u"XMPP URI used: {}".format(url),2) | |
377 # XXX: if we have not xmpp: URI here, we'll take the data as a file path | |
378 pubsub_service = parsed_url.path | |
379 pubsub_data = urlparse.parse_qs(parsed_url.query) | |
380 try: | |
381 pubsub_node = pubsub_data['node'][0] | |
382 except KeyError: | |
383 self.disp(u'No node found in xmpp: URI, can\'t retrieve item', error=True) | |
384 self.host.quit(1) | |
385 pubsub_item = pubsub_data.get('item',[None])[0] | |
386 if pubsub_item is not None: | |
387 command = 'edit' # XXX: edit command is only used internaly, it similar to last, but with the item given in the URL | |
388 else: | |
389 command = 'new' | |
390 | |
391 if command in ('new', 'last', 'edit'): | |
351 # we get current syntax to determine file extension | 392 # we get current syntax to determine file extension |
352 current_syntax = self.host.bridge.getParamA("Syntax", "Composition", "value", self.profile) | 393 current_syntax = self.host.bridge.getParamA("Syntax", "Composition", "value", self.profile) |
353 # we now create a temporary file | 394 # we now create a temporary file |
354 tmp_suff = '.' + SYNTAX_EXT.get(current_syntax, SYNTAX_EXT['']) | 395 tmp_suff = '.' + SYNTAX_EXT.get(current_syntax, SYNTAX_EXT['']) |
355 content_file_obj, content_file_path = self.getTmpFile(sat_conf, tmp_suff) | 396 content_file_obj, content_file_path = self.getTmpFile(sat_conf, tmp_suff) |
356 if item_lower == 'new': | 397 if command == 'new': |
357 self.disp(u'Editing a new blog item', 2) | 398 self.disp(u'Editing a new blog item', 2) |
358 mb_data = None | 399 mb_data = None |
359 elif item_lower == 'last': | 400 elif command in ('last', 'edit'): |
360 self.disp(u'Editing last published item', 2) | 401 self.disp(u'Editing requested published item', 2) |
361 try: | 402 try: |
362 mb_data = self.host.bridge.mbGet('', '', 1, [], {}, self.profile)[0][0] | 403 items_ids = [pubsub_item] if pubsub_item is not None else [] |
404 mb_data = self.host.bridge.mbGet(pubsub_service, pubsub_node, 1, items_ids, {}, self.profile)[0][0] | |
363 except Exception as e: | 405 except Exception as e: |
364 self.disp(u"Error while retrieving last item: {}".format(e)) | 406 self.disp(u"Error while retrieving last item: {}".format(e)) |
365 self.host.quit(1) | 407 self.host.quit(1) |
366 | 408 |
367 content = mb_data['content_xhtml'] | 409 content = mb_data['content_xhtml'] |
369 content = self.host.bridge.syntaxConvert(content, 'XHTML', current_syntax, False, self.profile) | 411 content = self.host.bridge.syntaxConvert(content, 'XHTML', current_syntax, False, self.profile) |
370 content_file_obj.write(content.encode('utf-8')) | 412 content_file_obj.write(content.encode('utf-8')) |
371 content_file_obj.seek(0) | 413 content_file_obj.seek(0) |
372 else: | 414 else: |
373 mb_data = None | 415 mb_data = None |
374 if item_lower == 'current': | 416 if command == 'current': |
375 # use wants to continue current draft | 417 # use wants to continue current draft |
376 content_file_path = self.getCurrentFile(sat_conf, self.profile) | 418 content_file_path = self.getCurrentFile(sat_conf, self.profile) |
377 self.disp(u'Continuing edition of current draft', 2) | 419 self.disp(u'Continuing edition of current draft', 2) |
378 else: | 420 else: |
379 # for now we taxe the item as a file path | 421 # we consider the item as a file path |
380 content_file_path = os.path.expanduser(self.args.item) | 422 content_file_path = os.path.expanduser(self.args.item) |
381 content_file_obj = open(content_file_path, 'r+b') | 423 content_file_obj = open(content_file_path, 'r+b') |
382 current_syntax = self.guessSyntaxFromPath(sat_conf, content_file_path) | 424 current_syntax = self.guessSyntaxFromPath(sat_conf, content_file_path) |
383 | 425 |
384 self.disp(u"Syntax used: {}".format(current_syntax), 1) | 426 self.disp(u"Syntax used: {}".format(current_syntax), 1) |
385 self.edit(sat_conf, content_file_path, content_file_obj, mb_data=mb_data) | 427 self.edit(sat_conf, content_file_path, content_file_obj, pubsub_service, pubsub_node, mb_data=mb_data) |
386 | 428 |
387 | 429 |
388 class Preview(base.CommandBase, BlogCommon): | 430 class Preview(base.CommandBase, BlogCommon): |
389 | 431 |
390 def __init__(self, host): | 432 def __init__(self, host): |