Mercurial > libervia-backend
comparison frontends/src/jp/cmd_blog.py @ 1885:edd8dc8df1b9
jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 05 Mar 2016 19:21:35 +0100 |
parents | abb2f253188e |
children | f3db27508b31 |
comparison
equal
deleted
inserted
replaced
1884:0fe69871b71f | 1885:edd8dc8df1b9 |
---|---|
99 return k | 99 return k |
100 | 100 |
101 # if not found, we use current syntax | 101 # if not found, we use current syntax |
102 return self.host.bridge.getParamA("Syntax", "Composition", "value", self.profile) | 102 return self.host.bridge.getParamA("Syntax", "Composition", "value", self.profile) |
103 | 103 |
104 def parse_args(self, cmd_line, **format_kw): | |
105 """Parse command arguments | |
106 | |
107 @param cmd_line(unicode): command line as found in sat.conf | |
108 @param format_kw: keywords used for formmating | |
109 @return (list(unicode)): list of arguments to pass to subprocess function | |
110 """ | |
111 try: | |
112 # we split the arguments and add the known fields | |
113 # we split arguments first to avoid escaping issues in file names | |
114 return [a.format(**format_kw) for a in shlex.split(cmd_line)] | |
115 except ValueError as e: | |
116 self.disp(u"Couldn't parse editor cmd [{cmd}]: {reason}".format(cmd=cmd_line, reason=e)) | |
117 return [] | |
118 | |
104 | 119 |
105 class Edit(base.CommandBase, BlogCommon): | 120 class Edit(base.CommandBase, BlogCommon): |
106 | 121 |
107 def __init__(self, host): | 122 def __init__(self, host): |
108 super(Edit, self).__init__(host, 'edit', use_verbose=True, help=_(u'edit an existing or new blog post')) | 123 super(Edit, self).__init__(host, 'edit', use_verbose=True, help=_(u'edit an existing or new blog post')) |
203 # is there custom arguments in sat.conf ? | 218 # is there custom arguments in sat.conf ? |
204 editor_args = config.getConfig(sat_conf, 'jp', 'blog_editor_args', Exception) | 219 editor_args = config.getConfig(sat_conf, 'jp', 'blog_editor_args', Exception) |
205 except (NoOptionError, NoSectionError): | 220 except (NoOptionError, NoSectionError): |
206 # no, we check if we know the editor and have special arguments | 221 # no, we check if we know the editor and have special arguments |
207 editor_args = EDITOR_ARGS_MAGIC.get(os.path.basename(editor), '') | 222 editor_args = EDITOR_ARGS_MAGIC.get(os.path.basename(editor), '') |
208 try: | 223 args = self.parse_args(editor_args, content_file=content_file_path, metadata_file=meta_file_path) |
209 # we split the arguments and add the known fields | |
210 # we split arguments first to avoid escaping issues in file names | |
211 args = [a.format(content_file=content_file_path, metadata_file=meta_file_path) for a in shlex.split(editor_args)] | |
212 except ValueError as e: | |
213 self.disp(u"Couldn't parse editor cmd [{cmd}]: {reason}".format(cmd=editor_args, reason=e)) | |
214 args = [] | |
215 if not args: | 224 if not args: |
216 args = [content_file_path] | 225 args = [content_file_path] |
217 editor_exit = subprocess.call([editor] + args) | 226 editor_exit = subprocess.call([editor] + args) |
218 | 227 |
219 # we send the file if edition was a success | 228 # we send the file if edition was a success |
301 except Exception as e: | 310 except Exception as e: |
302 self.disp(u"Error while retrieving last comment: {}".format(e)) | 311 self.disp(u"Error while retrieving last comment: {}".format(e)) |
303 self.host.quit(1) | 312 self.host.quit(1) |
304 | 313 |
305 content = mb_data['content_xhtml'] | 314 content = mb_data['content_xhtml'] |
306 if current_syntax != 'XHTML': | 315 if content and current_syntax != 'XHTML': |
307 content = self.host.bridge.syntaxConvert(content, 'XHTML', current_syntax, False, self.profile) | 316 content = self.host.bridge.syntaxConvert(content, 'XHTML', current_syntax, False, self.profile) |
308 content_file_obj.write(content.encode('utf-8')) | 317 content_file_obj.write(content.encode('utf-8')) |
309 content_file_obj.seek(0) | 318 content_file_obj.seek(0) |
310 | 319 |
311 self.edit(sat_conf, content_file_path, content_file_obj, mb_data=mb_data) | 320 self.edit(sat_conf, content_file_path, content_file_obj, mb_data=mb_data) |
324 # we implement showPreview here so we don't have to import webbroser and urllib | 333 # we implement showPreview here so we don't have to import webbroser and urllib |
325 # when preview is not used | 334 # when preview is not used |
326 url = 'file:{}'.format(self.urllib.quote(self.preview_file_path)) | 335 url = 'file:{}'.format(self.urllib.quote(self.preview_file_path)) |
327 self.webbrowser.open_new_tab(url) | 336 self.webbrowser.open_new_tab(url) |
328 | 337 |
338 def _launchPreviewExt(self, cmd_line, opt_name): | |
339 url = 'file:{}'.format(self.urllib.quote(self.preview_file_path)) | |
340 args = self.parse_args(cmd_line, url=url, preview_file=self.preview_file_path) | |
341 if not args: | |
342 self.disp(u"Couln't find command in \"{name}\", abording".format(name=opt_name), error=True) | |
343 self.host.quit(1) | |
344 subprocess.Popen(args) | |
345 | |
346 def openPreviewExt(self): | |
347 self._launchPreviewExt(self.open_cb_cmd, "blog_preview_open_cmd") | |
348 | |
349 def updatePreviewExt(self): | |
350 self._launchPreviewExt(self.update_cb_cmd, "blog_preview_update_cmd") | |
351 | |
329 def updateContent(self): | 352 def updateContent(self): |
330 with open(self.current_file_path, 'rb') as f: | 353 with open(self.content_file_path, 'rb') as f: |
331 content_xhtml = f.read().decode('utf-8') | 354 content = f.read().decode('utf-8') |
332 if self.syntax != 'XHTML': | 355 if content and self.syntax != 'XHTML': |
333 # we use safe=True because we want to have a preview as close as possible to what the | 356 # we use safe=True because we want to have a preview as close as possible to what the |
334 # people will see | 357 # people will see |
335 content_xhtml = self.host.bridge.syntaxConvert(content_xhtml, self.syntax, 'XHTML', True, self.profile) | 358 content = self.host.bridge.syntaxConvert(content, self.syntax, 'XHTML', True, self.profile) |
336 | 359 |
337 xhtml = (u'<html xmlns="http://www.w3.org/1999/xhtml">' + | 360 xhtml = (u'<html xmlns="http://www.w3.org/1999/xhtml">' + |
338 u'<head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" /></head>'+ | 361 u'<head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" /></head>'+ |
339 '<body>{}</body>' + | 362 '<body>{}</body>' + |
340 u'</html>').format(content_xhtml) | 363 u'</html>').format(content) |
341 | 364 |
342 with open(self.preview_file_path, 'wb') as f: | 365 with open(self.preview_file_path, 'wb') as f: |
343 f.write(xhtml.encode('utf-8')) | 366 f.write(xhtml.encode('utf-8')) |
344 | 367 |
345 def start(self): | 368 def start(self): |
368 inotify=None | 391 inotify=None |
369 | 392 |
370 sat_conf = config.parseMainConf() | 393 sat_conf = config.parseMainConf() |
371 SYNTAX_EXT.update(config.getConfig(sat_conf, 'jp', CONF_SYNTAX_EXT, {})) | 394 SYNTAX_EXT.update(config.getConfig(sat_conf, 'jp', CONF_SYNTAX_EXT, {})) |
372 | 395 |
373 open_cb = self.showPreview | 396 try: |
374 update_cb = self.showPreview | 397 self.open_cb_cmd = config.getConfig(sat_conf, 'jp', "blog_preview_open_cmd", Exception) |
398 except (NoOptionError, NoSectionError): | |
399 self.open_cb_cmd = None | |
400 open_cb = self.showPreview | |
401 else: | |
402 open_cb = self.openPreviewExt | |
403 | |
404 self.update_cb_cmd = config.getConfig(sat_conf, 'jp', "blog_preview_update_cmd", self.open_cb_cmd) | |
405 if self.update_cb_cmd is None: | |
406 update_cb = self.showPreview | |
407 else: | |
408 update_cb = self.updatePreviewExt | |
375 | 409 |
376 # which file do we need to edit? | 410 # which file do we need to edit? |
377 if self.args.file == 'current': | 411 if self.args.file == 'current': |
378 self.current_file_path = self.getCurrentFile(sat_conf) | 412 self.content_file_path = self.getCurrentFile(sat_conf) |
379 else: | 413 else: |
380 self.current_file_path = os.path.abspath(self.args.file) | 414 self.content_file_path = os.path.abspath(self.args.file) |
381 | 415 |
382 self.syntax = self.guessSyntaxFromPath(sat_conf, self.current_file_path) | 416 self.syntax = self.guessSyntaxFromPath(sat_conf, self.content_file_path) |
383 | 417 |
384 | 418 |
385 # at this point the syntax is converted, we can display the preview | 419 # at this point the syntax is converted, we can display the preview |
386 preview_file = tempfile.NamedTemporaryFile(suffix='.xhtml', delete=False) | 420 preview_file = tempfile.NamedTemporaryFile(suffix='.xhtml', delete=False) |
387 self.preview_file_path = preview_file.name | 421 self.preview_file_path = preview_file.name |