diff 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
line wrap: on
line diff
--- a/frontends/src/jp/cmd_blog.py	Tue Mar 22 23:33:55 2016 +0100
+++ b/frontends/src/jp/cmd_blog.py	Thu Mar 24 18:38:04 2016 +0100
@@ -249,7 +249,8 @@
 
         return mb_data, meta_file_path
 
-    def edit(self, sat_conf, content_file_path, content_file_obj, mb_data=None):
+    def edit(self, sat_conf, content_file_path, content_file_obj,
+             pubsub_service, pubsub_node, mb_data=None):
         """Edit the file contening the content using editor, and publish it"""
         item_ori_mb_data = mb_data
         # we first create metadata file
@@ -329,7 +330,7 @@
                     mb_data['id'] = item_ori_mb_data['id']
 
                 try:
-                    self.host.bridge.mbSend('', '', mb_data, self.profile)
+                    self.host.bridge.mbSend(pubsub_service, pubsub_node, mb_data, self.profile)
                 except Exception as e:
                     self.disp(u"Error while sending your blog, the temporary files have been kept at {content_path} and {meta_path}: {reason}".format(
                         content_path=content_file_path, meta_path=meta_file_path, reason=e), error=True)
@@ -341,25 +342,66 @@
             self.secureUnlink(sat_conf, meta_file_path)
 
     def start(self):
-        item_lower = self.args.item.lower()
+        command = self.args.item.lower()
         sat_conf = config.parseMainConf()
         # if there are user defined extension, we use them
         SYNTAX_EXT.update(config.getConfig(sat_conf, 'jp', CONF_SYNTAX_EXT, {}))
         current_syntax = None
+        pubsub_service = pubsub_node = ''
+        pubsub_item = None
 
-        if item_lower in ('new', 'last'):
+        if command not in ('new', 'last', 'current'):
+            # we have probably an URL, we try to parse it
+            import urlparse
+            url = self.args.item
+            parsed_url = urlparse.urlsplit(url)
+            if parsed_url.scheme.startswith('http'):
+                self.disp(u"{} URL found, trying to find associated xmpp: URI".format(parsed_url.scheme.upper()),1)
+                # HTTP URL, we try to find xmpp: links
+                try:
+                    from lxml import etree
+                except ImportError:
+                    self.disp(u"lxml module must be installed to use http(s) scheme, please install it with \"pip install lxml\"", error=True)
+                    self.host.quit(1)
+                parser = etree.HTMLParser()
+                root = etree.parse(url, parser)
+                links = root.xpath("//link[@rel='alternate' and starts-with(@href, 'xmpp:')]")
+                if not links:
+                    self.disp(u'Could not find alternate "xmpp:" URI, can\'t find associated XMPP PubSub node/item', error=True)
+                    self.host.quit(1)
+                url = links[0].get('href')
+                parsed_url = urlparse.urlsplit(url)
+
+            if parsed_url.scheme == 'xmpp':
+                self.disp(u"XMPP URI used: {}".format(url),2)
+                # XXX: if we have not xmpp: URI here, we'll take the data as a file path
+                pubsub_service = parsed_url.path
+                pubsub_data = urlparse.parse_qs(parsed_url.query)
+                try:
+                    pubsub_node = pubsub_data['node'][0]
+                except KeyError:
+                    self.disp(u'No node found in xmpp: URI, can\'t retrieve item', error=True)
+                    self.host.quit(1)
+                pubsub_item = pubsub_data.get('item',[None])[0]
+                if pubsub_item is not None:
+                    command = 'edit' # XXX: edit command is only used internaly, it similar to last, but with the item given in the URL
+                else:
+                    command = 'new'
+
+        if command in ('new', 'last', 'edit'):
             # we get current syntax to determine file extension
             current_syntax = self.host.bridge.getParamA("Syntax", "Composition", "value", self.profile)
             # we now create a temporary file
             tmp_suff = '.' + SYNTAX_EXT.get(current_syntax, SYNTAX_EXT[''])
             content_file_obj, content_file_path = self.getTmpFile(sat_conf, tmp_suff)
-            if item_lower == 'new':
+            if command == 'new':
                 self.disp(u'Editing a new blog item', 2)
                 mb_data = None
-            elif item_lower == 'last':
-                self.disp(u'Editing last published item', 2)
+            elif command in ('last', 'edit'):
+                self.disp(u'Editing requested published item', 2)
                 try:
-                    mb_data = self.host.bridge.mbGet('', '', 1, [], {}, self.profile)[0][0]
+                    items_ids = [pubsub_item] if pubsub_item is not None else []
+                    mb_data = self.host.bridge.mbGet(pubsub_service, pubsub_node, 1, items_ids, {}, self.profile)[0][0]
                 except Exception as e:
                     self.disp(u"Error while retrieving last item: {}".format(e))
                     self.host.quit(1)
@@ -371,18 +413,18 @@
                 content_file_obj.seek(0)
         else:
             mb_data = None
-            if item_lower == 'current':
+            if command == 'current':
                 # use wants to continue current draft
                 content_file_path = self.getCurrentFile(sat_conf, self.profile)
                 self.disp(u'Continuing edition of current draft', 2)
             else:
-                # for now we taxe the item as a file path
+                # we consider the item as a file path
                 content_file_path = os.path.expanduser(self.args.item)
             content_file_obj = open(content_file_path, 'r+b')
             current_syntax = self.guessSyntaxFromPath(sat_conf, content_file_path)
 
         self.disp(u"Syntax used: {}".format(current_syntax), 1)
-        self.edit(sat_conf, content_file_path, content_file_obj, mb_data=mb_data)
+        self.edit(sat_conf, content_file_path, content_file_obj, pubsub_service, pubsub_node, mb_data=mb_data)
 
 
 class Preview(base.CommandBase, BlogCommon):