# HG changeset patch # User Goffi # Date 1457086961 -3600 # Node ID a97db84c048de43494c60e3466bf7e3308c20c36 # Parent 1088bf7b28e7c49618bc822651e6a6949b109767 jp (blog): moved common method in a BlogCommon class + added "current" as an item keyword for blog/edit diff -r 1088bf7b28e7 -r a97db84c048d frontends/src/jp/cmd_blog.py --- a/frontends/src/jp/cmd_blog.py Fri Mar 04 10:33:28 2016 +0100 +++ b/frontends/src/jp/cmd_blog.py Fri Mar 04 11:22:41 2016 +0100 @@ -62,17 +62,46 @@ URL_REDIRECT_PREFIX = 'url_redirect_' -def getTmpDir(sat_conf): - """Return directory used to store temporary files +class BlogCommon(object): + def getTmpDir(self, sat_conf): + """Return directory used to store temporary files + + @param sat_conf(ConfigParser.ConfigParser): instance opened on sat configuration + @return (str): path to the dir + """ + local_dir = config.getConfig(sat_conf, '', 'local_dir', Exception) + return os.path.join(local_dir, BLOG_TMP_DIR) - @param sat_conf(ConfigParser.ConfigParser): instance opened on sat configuration - @return (str): path to the dir - """ - local_dir = config.getConfig(sat_conf, '', 'local_dir', Exception) - return os.path.join(local_dir, BLOG_TMP_DIR) + def getCurrentFile(self, sat_conf): + # we guess the blog item currently edited by choosing + # the most recent file corresponding to temp file pattern + # in tmp_dir, excluding metadata files + tmp_dir = self.getTmpDir(sat_conf) + available = [path for path in glob.glob(os.path.join(tmp_dir, 'blog_*')) if not path.endswith(METADATA_SUFF)] + if not available: + self.disp(u"Counldn't find any content draft in {path}".format(path=tmp_dir), error=True) + self.host.quit(1) + return max(available, key=lambda path: os.stat(path).st_mtime) + + def guessSyntaxFromPath(self, sat_conf, path): + """Return syntax guessed according to filename extension + + @param sat_conf(ConfigParser.ConfigParser): instance opened on sat configuration + @param path(str): path to the content file + @return(unicode): syntax to use + """ + # we first try to guess syntax with extension + ext = os.path.splitext(path)[1][1:] # we get extension without the '.' + if ext: + for k,v in SYNTAX_EXT.iteritems(): + if ext == v: + return v + + # if not found, we use current syntax + return self.host.bridge.getParamA("Syntax", "Composition", "value", self.profile) -class Edit(base.CommandBase): +class Edit(base.CommandBase, BlogCommon): def __init__(self, host): super(Edit, self).__init__(host, 'edit', use_verbose=True, help=_(u'edit an existing or new blog post')) @@ -90,7 +119,7 @@ @param tmp_suff (str): suffix to use for the filename @return (tuple(file, str)): opened (w+b) file object and file path """ - tmp_dir = getTmpDir(sat_conf) + tmp_dir = self.getTmpDir(sat_conf) if not os.path.exists(tmp_dir): try: os.makedirs(tmp_dir) @@ -238,21 +267,32 @@ os.unlink(meta_file_path) def start(self): - # we get current syntax to determine file extension - current_syntax = self.host.bridge.getParamA("Syntax", "Composition", "value", self.profile) - self.disp(u"Current syntax: {}".format(current_syntax), 1) + item_lower = 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 - # 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 == 'current': + # use wants to continue current draft + content_file_path = self.getCurrentFile(sat_conf) + content_file_obj = open(content_file_path, 'r+b') + current_syntax = self.guessSyntaxFromPath(sat_conf, content_file_path) + else: + # 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) - item_lower = self.args.item.lower() + self.disp(u"Syntax used: {}".format(current_syntax), 1) + if item_lower == 'new': self.disp(u'Editing a new blog item', 2) - self.edit(sat_conf, content_file_path, content_file_obj) + mb_data = None + elif item_lower == 'current': + self.disp(u'Continuing edition of current draft', 2) + mb_data = None elif item_lower == 'last': self.disp(u'Editing last published item', 2) try: @@ -266,62 +306,51 @@ content = self.host.bridge.syntaxConvert(content, 'XHTML', current_syntax, False, self.profile) content_file_obj.write(content.encode('utf-8')) content_file_obj.seek(0) - self.edit(sat_conf, content_file_path, content_file_obj, mb_data=mb_data) + + self.edit(sat_conf, content_file_path, content_file_obj, mb_data=mb_data) -class Preview(base.CommandBase): +class Preview(base.CommandBase, BlogCommon): def __init__(self, host): - super(Preview, self).__init__(host, 'preview', use_verbose=True, help=_(u'preview a blog content')) + super(Preview, self).__init__(host, 'preview', help=_(u'preview a blog content')) def add_parser_options(self): self.parser.add_argument("file", type=base.unicode_decoder, nargs='?', default=u'current', help=_(u"path to the content file")) + def showPreview(self, content_xhtml, file_obj): + import webbrowser + import urllib + xhtml = (u'' + + u''+ + '{}' + + u'').format(content_xhtml) + file_obj.write(xhtml.encode('utf-8')) + url = 'file:{}'.format(urllib.quote(file_obj.name)) + webbrowser.open_new_tab(url) + def start(self): sat_conf = config.parseMainConf() + SYNTAX_EXT.update(config.getConfig(sat_conf, 'jp', CONF_SYNTAX_EXT, {})) # which file do we need to edit? if self.args.file == 'current': - # we guess the blog item currently edited by choosing - # the most recent file corresponding to temp file pattern - # in tmp_dir, excluding metadata files - tmp_dir = getTmpDir(sat_conf) - available = [path for path in glob.glob(os.path.join(tmp_dir, 'blog_*')) if not path.endswith(METADATA_SUFF)] - if not available: - self.disp(u"Counldn't find any content draft in {path}".format(path=tmp_dir), error=True) - self.host.quit(1) - current_path = max(available, key=lambda path: os.stat(path).st_mtime) + current_file_path = self.getCurrentFile(sat_conf) else: - current_path = os.path.abspath(self.args.file) + current_file_path = os.path.abspath(self.args.file) + + syntax = self.guessSyntaxFromPath(sat_conf, current_file_path) - # we first try to guess syntax with extension - SYNTAX_EXT.update(config.getConfig(sat_conf, 'jp', CONF_SYNTAX_EXT, {})) - ext = os.path.splitext(current_path)[1][1:] # we get extension without the '.' - syntax = None - if ext: - for k,v in SYNTAX_EXT.iteritems(): - if ext == v: - syntax = k - break + if syntax != 'XHTML': + with open(current_file_path, 'rb') as f: + content_xhtml = self.host.bridge.syntaxConvert(f.read(), syntax, 'XHTML', False, self.profile) - # if not found, we use current syntax - if syntax is None: - syntax = self.host.bridge.getParamA("Syntax", "Composition", "value", self.profile) - if syntax != 'XHTML': - with open(current_path, 'rb') as f: - content_xhtml = self.host.bridge.syntaxConvert(f.read(), syntax, 'XHTML', False, self.profile) - import webbrowser - import urllib + # at this point the syntax is converted, we can display the preview + with tempfile.NamedTemporaryFile(suffix='.xhtml', delete=False) as f: # XXX: we don't delete file automatically because browser need it (and webbrowser.open can return before it is read) self.disp(u'temporary file created at {}\nthis file will NOT BE DELETED AUTOMATICALLY, please delete it yourself when you have finished'.format(f.name)) - xhtml = (u'' + - u''+ - '{}' + - u'').format(content_xhtml) - f.write(xhtml.encode('utf-8')) - url = 'file:{}'.format(urllib.quote(f.name)) - webbrowser.open_new_tab(url) + self.showPreview(content_xhtml, f) class Import(base.CommandAnswering):