jp (blog, common): various fixes in common and blog:
- parse_args has been moved to common
- cat_dir is converted to str on BaseEdit init, so it can be use to make str path for files manipulation
- fixed use of EDITOR_ARGS_MAGIC when use_metadata is False
- fixed unlink of metadata files when use_metadata is False
This commit is contained in:
parent
e22336c6f2
commit
2449721982
2 changed files with 46 additions and 39 deletions
|
|
@ -33,7 +33,6 @@ import os
|
|||
import time
|
||||
import tempfile
|
||||
import subprocess
|
||||
import shlex
|
||||
from sat.tools.common import data_format
|
||||
|
||||
__commands__ = ["Blog"]
|
||||
|
|
@ -47,7 +46,7 @@ SYNTAX_EXT = {
|
|||
|
||||
|
||||
CONF_SYNTAX_EXT = 'syntax_ext_dict'
|
||||
BLOG_TMP_DIR=u"blog"
|
||||
BLOG_TMP_DIR = u"blog"
|
||||
# key to remove from metadata tmp file if they exist
|
||||
KEY_TO_REMOVE_METADATA = ('id','content', 'content_xhtml', 'comments_node', 'comments_service', 'updated')
|
||||
|
||||
|
|
@ -97,21 +96,6 @@ class BlogCommon(object):
|
|||
# if not found, we use current syntax
|
||||
return self.host.bridge.getParamA("Syntax", "Composition", "value", self.profile)
|
||||
|
||||
def parse_args(self, cmd_line, **format_kw):
|
||||
"""Parse command arguments
|
||||
|
||||
@param cmd_line(unicode): command line as found in sat.conf
|
||||
@param format_kw: keywords used for formmating
|
||||
@return (list(unicode)): list of arguments to pass to subprocess function
|
||||
"""
|
||||
try:
|
||||
# we split the arguments and add the known fields
|
||||
# we split arguments first to avoid escaping issues in file names
|
||||
return [a.format(**format_kw) for a in shlex.split(cmd_line)]
|
||||
except ValueError as e:
|
||||
self.disp(u"Couldn't parse editor cmd [{cmd}]: {reason}".format(cmd=cmd_line, reason=e))
|
||||
return []
|
||||
|
||||
|
||||
class Get(base.CommandBase, BlogCommon):
|
||||
TEMPLATE = u"blog/articles.html"
|
||||
|
|
@ -423,7 +407,7 @@ class Preview(base.CommandBase, BlogCommon):
|
|||
|
||||
def _launchPreviewExt(self, cmd_line, opt_name):
|
||||
url = 'file:{}'.format(self.urllib.quote(self.preview_file_path))
|
||||
args = self.parse_args(cmd_line, url=url, preview_file=self.preview_file_path)
|
||||
args = common.parse_args(self.host, cmd_line, url=url, preview_file=self.preview_file_path)
|
||||
if not args:
|
||||
self.disp(u"Couln't find command in \"{name}\", abording".format(name=opt_name), error=True)
|
||||
self.host.quit(1)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import time
|
|||
import tempfile
|
||||
import subprocess
|
||||
import glob
|
||||
import shlex
|
||||
|
||||
# defaut arguments used for some known editors (editing with metadata)
|
||||
VIM_SPLIT_ARGS = "-c 'vsplit|wincmd w|next|wincmd w'"
|
||||
|
|
@ -50,7 +51,7 @@ def getTmpDir(sat_conf, cat_dir, sub_dir=None):
|
|||
"""Return directory used to store temporary files
|
||||
|
||||
@param sat_conf(ConfigParser.ConfigParser): instance opened on sat configuration
|
||||
@param cat_dir(str): directory of the category (e.g. "blog")
|
||||
@param cat_dir(unicode): directory of the category (e.g. "blog")
|
||||
@param sub_dir(str): sub directory where data need to be put
|
||||
profile can be used here, or special directory name
|
||||
sub_dir will be escaped to be usable in path (use regex.pathUnescape to find
|
||||
|
|
@ -58,12 +59,28 @@ def getTmpDir(sat_conf, cat_dir, sub_dir=None):
|
|||
@return (str): path to the dir
|
||||
"""
|
||||
local_dir = config.getConfig(sat_conf, '', 'local_dir', Exception)
|
||||
path = [local_dir, cat_dir]
|
||||
path = [local_dir.encode('utf-8'), cat_dir.encode('utf-8')]
|
||||
if sub_dir is not None:
|
||||
path.append(regex.pathEscape(sub_dir))
|
||||
return os.path.join(*path)
|
||||
|
||||
|
||||
def parse_args(host, cmd_line, **format_kw):
|
||||
"""Parse command arguments
|
||||
|
||||
@param cmd_line(unicode): command line as found in sat.conf
|
||||
@param format_kw: keywords used for formating
|
||||
@return (list(unicode)): list of arguments to pass to subprocess function
|
||||
"""
|
||||
try:
|
||||
# we split the arguments and add the known fields
|
||||
# we split arguments first to avoid escaping issues in file names
|
||||
return [a.format(**format_kw) for a in shlex.split(cmd_line)]
|
||||
except ValueError as e:
|
||||
host.disp(u"Couldn't parse editor cmd [{cmd}]: {reason}".format(cmd=cmd_line, reason=e))
|
||||
return []
|
||||
|
||||
|
||||
class BaseEdit(object):
|
||||
u"""base class for editing commands
|
||||
|
||||
|
|
@ -71,7 +88,7 @@ class BaseEdit(object):
|
|||
It works with temporary files in SàT local_dir, in a "cat_dir" subdir
|
||||
"""
|
||||
|
||||
def __init__(self, host, cat_dir, use_metadata=True):
|
||||
def __init__(self, host, cat_dir, use_metadata=False):
|
||||
"""
|
||||
@param sat_conf(ConfigParser.ConfigParser): instance opened on sat configuration
|
||||
@param cat_dir(unicode): directory to use for drafts
|
||||
|
|
@ -82,7 +99,7 @@ class BaseEdit(object):
|
|||
"""
|
||||
self.host = host
|
||||
self.sat_conf = config.parseMainConf()
|
||||
self.cat_dir = cat_dir.encode('utf-8')
|
||||
self.cat_dir_str = cat_dir.encode('utf-8')
|
||||
self.use_metadata = use_metadata
|
||||
|
||||
def add_parser_options(self):
|
||||
|
|
@ -98,12 +115,12 @@ class BaseEdit(object):
|
|||
"""
|
||||
if not os.path.isfile(path):
|
||||
raise OSError(u"path must link to a regular file")
|
||||
if not path.startswith(getTmpDir(self.sat_conf, self.cat_dir)):
|
||||
if not path.startswith(getTmpDir(self.sat_conf, self.cat_dir_str)):
|
||||
self.disp(u"File {} is not in SàT temporary hierarchy, we do not remove it".format(path.decode('utf-8')), 2)
|
||||
return
|
||||
# we have 2 files per draft with use_metadata, so we double max
|
||||
unlink_max = SECURE_UNLINK_MAX * 2 if self.use_metadata else SECURE_UNLINK_MAX
|
||||
backup_dir = getTmpDir(self.sat_conf, self.cat_dir, SECURE_UNLINK_DIR)
|
||||
backup_dir = getTmpDir(self.sat_conf, self.cat_dir_str, SECURE_UNLINK_DIR)
|
||||
if not os.path.exists(backup_dir):
|
||||
os.makedirs(backup_dir)
|
||||
filename = os.path.basename(path)
|
||||
|
|
@ -150,11 +167,14 @@ class BaseEdit(object):
|
|||
editor_args = config.getConfig(self.sat_conf, 'jp', editor_args_opt, Exception)
|
||||
except (NoOptionError, NoSectionError):
|
||||
# no, we check if we know the editor and have special arguments
|
||||
editor_args = EDITOR_ARGS_MAGIC.get(os.path.basename(editor), '')
|
||||
if self.use_metadata:
|
||||
editor_args = EDITOR_ARGS_MAGIC.get(os.path.basename(editor), '')
|
||||
else:
|
||||
editor_args = ''
|
||||
parse_kwargs = {'content_file': content_file_path}
|
||||
if self.use_metadata:
|
||||
parse_kwargs['metadata_file'] = meta_file_path
|
||||
args = self.parse_args(editor_args, **parse_kwargs)
|
||||
args = parse_args(self.host, editor_args, **parse_kwargs)
|
||||
if not args:
|
||||
args = [content_file_path]
|
||||
|
||||
|
|
@ -198,20 +218,21 @@ class BaseEdit(object):
|
|||
self.host.quit()
|
||||
|
||||
if len(content) == 0:
|
||||
self.disp(u"Content is empty, cancelling the blog edition")
|
||||
if not content_file_path.startswith(getTmpDir(self.sat_conf, self.cat_dir)):
|
||||
self.disp(u"Content is empty, cancelling the edition")
|
||||
if not content_file_path.startswith(getTmpDir(self.sat_conf, self.cat_dir_str)):
|
||||
self.disp(u"File are not in SàT temporary hierarchy, we do not remove them", 2)
|
||||
self.host.quit()
|
||||
self.disp(u"Deletion of {}".format(content_file_path.decode('utf-8')), 2)
|
||||
os.unlink(content_file_path)
|
||||
self.disp(u"Deletion of {}".format(meta_file_path.decode('utf-8')), 2)
|
||||
os.unlink(meta_file_path)
|
||||
if self.use_metadata:
|
||||
self.disp(u"Deletion of {}".format(meta_file_path.decode('utf-8')), 2)
|
||||
os.unlink(meta_file_path)
|
||||
self.host.quit()
|
||||
|
||||
# time to re-check the hash
|
||||
elif (tmp_ori_hash == hashlib.sha1(content).digest() and
|
||||
(not self.use_metadata or meta_ori == metadata)):
|
||||
self.disp(u"The content has not been modified, cancelling the blog edition")
|
||||
self.disp(u"The content has not been modified, cancelling the edition")
|
||||
self.host.quit()
|
||||
|
||||
else:
|
||||
|
|
@ -232,7 +253,8 @@ class BaseEdit(object):
|
|||
self.host.quit(1)
|
||||
|
||||
self.secureUnlink(content_file_path)
|
||||
self.secureUnlink(meta_file_path)
|
||||
if self.use_metadata:
|
||||
self.secureUnlink(meta_file_path)
|
||||
|
||||
def publish(self, content):
|
||||
# if metadata is needed, publish will be called with it last argument
|
||||
|
|
@ -244,7 +266,8 @@ class BaseEdit(object):
|
|||
@param suff (str): suffix to use for the filename
|
||||
@return (tuple(file, str)): opened (w+b) file object and file path
|
||||
"""
|
||||
tmp_dir = getTmpDir(self.sat_conf, self.cat_dir, self.profile.encode('utf-8'))
|
||||
cat_dir_str = self.cat_dir_str
|
||||
tmp_dir = getTmpDir(self.sat_conf, self.cat_dir_str, self.profile.encode('utf-8'))
|
||||
if not os.path.exists(tmp_dir):
|
||||
try:
|
||||
os.makedirs(tmp_dir)
|
||||
|
|
@ -253,8 +276,8 @@ class BaseEdit(object):
|
|||
path=tmp_dir, reason=e), error=True)
|
||||
self.host.quit(1)
|
||||
try:
|
||||
fd, path = tempfile.mkstemp(suffix=suff,
|
||||
prefix=time.strftime(self.cat_dir.encode('utf-8') + '_%Y-%m-%d_%H:%M:%S_'),
|
||||
fd, path = tempfile.mkstemp(suffix=suff.encode('utf-8'),
|
||||
prefix=time.strftime(cat_dir_str + '_%Y-%m-%d_%H:%M:%S_'),
|
||||
dir=tmp_dir, text=True)
|
||||
return os.fdopen(fd, 'w+b'), path
|
||||
except OSError as e:
|
||||
|
|
@ -267,11 +290,11 @@ class BaseEdit(object):
|
|||
@param profile(unicode): profile linked to the draft
|
||||
@return(str): full path of current file
|
||||
"""
|
||||
# we guess the blog item currently edited by choosing
|
||||
# we guess the item currently edited by choosing
|
||||
# the most recent file corresponding to temp file pattern
|
||||
# in tmp_dir, excluding metadata files
|
||||
cat_dir_str = self.cat_dir.encode('utf-8')
|
||||
tmp_dir = getTmpDir(self.sat_conf, cat_dir_str, profile.encode('utf-8'))
|
||||
cat_dir_str = self.cat_dir_str
|
||||
tmp_dir = getTmpDir(self.sat_conf, self.cat_dir_str, profile.encode('utf-8'))
|
||||
available = [path for path in glob.glob(os.path.join(tmp_dir, cat_dir_str + '_*')) if not path.endswith(METADATA_SUFF)]
|
||||
if not available:
|
||||
self.disp(u"Could not find any content draft in {path}".format(path=tmp_dir), error=True)
|
||||
|
|
@ -284,7 +307,7 @@ class BaseEdit(object):
|
|||
|
||||
def getTmpSuff(self):
|
||||
"""return suffix used for content file"""
|
||||
return 'xml'
|
||||
return u'xml'
|
||||
|
||||
def getItemPath(self, item):
|
||||
"""retrieve item path (i.e. service and node) from item argument
|
||||
|
|
|
|||
Loading…
Reference in a new issue