annotate frontends/src/jp/common.py @ 2448:637ac234424f

plugin merge requests: first draft: this plugin allows to handle merge requests (i.e. requests to include a contribution in a project) by extendings tickets management. This plugin is made to be generic, independent from end user tools and from the kind of project where the contribution is requested to be merged.
author Goffi <goffi@goffi.org>
date Thu, 30 Nov 2017 20:44:25 +0100
parents 8b37a62336c3
children 0046283a285d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python2
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
2 # -*- coding: utf-8 -*-
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
3
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # jp: a SàT command line tool
2414
8b37a62336c3 misc: date update (yes it's a bit late :p )
Goffi <goffi@goffi.org>
parents: 2351
diff changeset
5 # Copyright (C) 2009-2017 Jérôme Poisson (goffi@goffi.org)
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
6
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # This program is free software: you can redistribute it and/or modify
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # it under the terms of the GNU Affero General Public License as published by
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # the Free Software Foundation, either version 3 of the License, or
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
10 # (at your option) any later version.
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
11
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # This program is distributed in the hope that it will be useful,
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
15 # GNU Affero General Public License for more details.
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
16
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # You should have received a copy of the GNU Affero General Public License
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
19
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
20 from sat_frontends.jp.constants import Const as C
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
21 from sat.core.i18n import _
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
22 from sat.core import exceptions
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
23 from sat.tools.common import regex
2279
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
24 from sat.tools.common import uri
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
25 from sat.tools.common.ansi import ANSI as A
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
26 from sat.tools import config
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
27 from ConfigParser import NoSectionError, NoOptionError
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
28 import json
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
29 import os
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
30 import os.path
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
31 import time
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
32 import tempfile
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
33 import subprocess
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
34 import glob
2273
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
35 import shlex
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
36
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
37 # defaut arguments used for some known editors (editing with metadata)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
38 VIM_SPLIT_ARGS = "-c 'vsplit|wincmd w|next|wincmd w'"
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
39 EMACS_SPLIT_ARGS = '--eval "(split-window-horizontally)"'
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
40 EDITOR_ARGS_MAGIC = {
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
41 'vim': VIM_SPLIT_ARGS + ' {content_file} {metadata_file}',
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
42 'gvim': VIM_SPLIT_ARGS + ' --nofork {content_file} {metadata_file}',
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
43 'emacs': EMACS_SPLIT_ARGS + ' {content_file} {metadata_file}',
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
44 'xemacs': EMACS_SPLIT_ARGS + ' {content_file} {metadata_file}',
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
45 'nano': ' -F {content_file} {metadata_file}',
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
46 }
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
47
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
48 SECURE_UNLINK_MAX = 10
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 SECURE_UNLINK_DIR = ".backup"
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 METADATA_SUFF = '_metadata.json'
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
51
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
52
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
53 def ansi_ljust(s, width):
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
54 """ljust method handling ANSI escape codes"""
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
55 cleaned = regex.ansiRemove(s)
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
56 return s + u' ' * (width - len(cleaned))
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
57
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
58
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
59 def ansi_center(s, width):
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
60 """ljust method handling ANSI escape codes"""
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
61 cleaned = regex.ansiRemove(s)
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
62 diff = width - len(cleaned)
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
63 half = diff/2
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
64 return half * u' ' + s + (half + diff % 2) * u' '
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
65
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
66
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
67 def ansi_rjust(s, width):
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
68 """ljust method handling ANSI escape codes"""
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
69 cleaned = regex.ansiRemove(s)
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
70 return u' ' * (width - len(cleaned)) + s
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
71
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
72
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
73 def getTmpDir(sat_conf, cat_dir, sub_dir=None):
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
74 """Return directory used to store temporary files
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
75
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
76 @param sat_conf(ConfigParser.ConfigParser): instance opened on sat configuration
2273
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
77 @param cat_dir(unicode): directory of the category (e.g. "blog")
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
78 @param sub_dir(str): sub directory where data need to be put
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
79 profile can be used here, or special directory name
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
80 sub_dir will be escaped to be usable in path (use regex.pathUnescape to find
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
81 initial str)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
82 @return (str): path to the dir
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
83 """
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
84 local_dir = config.getConfig(sat_conf, '', 'local_dir', Exception)
2273
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
85 path = [local_dir.encode('utf-8'), cat_dir.encode('utf-8')]
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
86 if sub_dir is not None:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
87 path.append(regex.pathEscape(sub_dir))
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
88 return os.path.join(*path)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
89
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
90
2273
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
91 def parse_args(host, cmd_line, **format_kw):
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
92 """Parse command arguments
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
93
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
94 @param cmd_line(unicode): command line as found in sat.conf
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
95 @param format_kw: keywords used for formating
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
96 @return (list(unicode)): list of arguments to pass to subprocess function
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
97 """
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
98 try:
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
99 # we split the arguments and add the known fields
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
100 # we split arguments first to avoid escaping issues in file names
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
101 return [a.format(**format_kw) for a in shlex.split(cmd_line)]
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
102 except ValueError as e:
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
103 host.disp(u"Couldn't parse editor cmd [{cmd}]: {reason}".format(cmd=cmd_line, reason=e))
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
104 return []
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
105
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
106
2279
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
107 def checkURI(args):
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
108 """check if args.node is an URI
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
109
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
110 if a valid xmpp: URI is found, args.service, args.node and args.item will be set
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
111 """
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
112 # FIXME: Q&D way to handle xmpp: uris, a generic way is needed
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
113 # and it should be merged with code in BaseEdit
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
114 if not args.service and args.node.startswith('xmpp:'):
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
115 try:
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
116 uri_data = uri.parseXMPPUri(args.node)
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
117 except ValueError:
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
118 pass
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
119 else:
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
120 if uri_data[u'type'] == 'pubsub':
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
121 args.service = uri_data[u'path']
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
122 args.node = uri_data[u'node']
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
123 if u'item' in uri_data:
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
124 try:
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
125 item = getattr(uri_data, 'item')
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
126 except AttributeError:
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
127 pass
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
128 else:
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
129 if item is None:
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
130 args.item = uri_data
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
131
e2f96cd1887b jp (cmd_pubsub): xmpp: uri handling, first draft
Goffi <goffi@goffi.org>
parents: 2276
diff changeset
132
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
133 class BaseEdit(object):
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
134 u"""base class for editing commands
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
135
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
136 This class allows to edit file for PubSub or something else.
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
137 It works with temporary files in SàT local_dir, in a "cat_dir" subdir
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
138 """
2351
3c0a3fae1862 jp (pubsub/node): added schema (set/edit/get) commands to manipulate PubSub node schema
Goffi <goffi@goffi.org>
parents: 2345
diff changeset
139 # use_items(bool): True if items are used, will then add item related options
3c0a3fae1862 jp (pubsub/node): added schema (set/edit/get) commands to manipulate PubSub node schema
Goffi <goffi@goffi.org>
parents: 2345
diff changeset
140 use_items=True
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
141
2273
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
142 def __init__(self, host, cat_dir, use_metadata=False):
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
143 """
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
144 @param sat_conf(ConfigParser.ConfigParser): instance opened on sat configuration
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
145 @param cat_dir(unicode): directory to use for drafts
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
146 this will be a sub-directory of SàT's local_dir
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
147 @param use_metadata(bool): True is edition need a second file for metadata
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
148 most of signature change with use_metadata with an additional metadata argument.
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
149 This is done to raise error if a command needs metadata but forget the flag, and vice versa
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
150 """
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
151 self.host = host
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
152 self.sat_conf = config.parseMainConf()
2273
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
153 self.cat_dir_str = cat_dir.encode('utf-8')
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
154 self.use_metadata = use_metadata
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
155
2270
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
156 def add_parser_options(self):
2351
3c0a3fae1862 jp (pubsub/node): added schema (set/edit/get) commands to manipulate PubSub node schema
Goffi <goffi@goffi.org>
parents: 2345
diff changeset
157 if self.use_items:
3c0a3fae1862 jp (pubsub/node): added schema (set/edit/get) commands to manipulate PubSub node schema
Goffi <goffi@goffi.org>
parents: 2345
diff changeset
158 group = self.parser.add_mutually_exclusive_group()
3c0a3fae1862 jp (pubsub/node): added schema (set/edit/get) commands to manipulate PubSub node schema
Goffi <goffi@goffi.org>
parents: 2345
diff changeset
159 group.add_argument("--force-item", action='store_true', help=_(u"don't use magic and take item argument as an actual item"))
3c0a3fae1862 jp (pubsub/node): added schema (set/edit/get) commands to manipulate PubSub node schema
Goffi <goffi@goffi.org>
parents: 2345
diff changeset
160 group.add_argument("--last-item", action='store_true', help=_(u"take last item instead of creating a new one if no item id is found"))
2270
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
161
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
162 def secureUnlink(self, path):
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
163 """Unlink given path after keeping it for a while
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
164
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
165 This method is used to prevent accidental deletion of a draft
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
166 If there are more file in SECURE_UNLINK_DIR than SECURE_UNLINK_MAX,
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
167 older file are deleted
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
168 @param path(str): file to unlink
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
169 """
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
170 if not os.path.isfile(path):
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
171 raise OSError(u"path must link to a regular file")
2273
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
172 if not path.startswith(getTmpDir(self.sat_conf, self.cat_dir_str)):
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
173 self.disp(u"File {} is not in SàT temporary hierarchy, we do not remove it".format(path.decode('utf-8')), 2)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
174 return
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
175 # we have 2 files per draft with use_metadata, so we double max
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
176 unlink_max = SECURE_UNLINK_MAX * 2 if self.use_metadata else SECURE_UNLINK_MAX
2273
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
177 backup_dir = getTmpDir(self.sat_conf, self.cat_dir_str, SECURE_UNLINK_DIR)
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
178 if not os.path.exists(backup_dir):
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
179 os.makedirs(backup_dir)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
180 filename = os.path.basename(path)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
181 backup_path = os.path.join(backup_dir, filename)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
182 # we move file to backup dir
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
183 self.host.disp(u"Backuping file {src} to {dst}".format(
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
184 src=path.decode('utf-8'), dst=backup_path.decode('utf-8')), 1)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
185 os.rename(path, backup_path)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
186 # and if we exceeded the limit, we remove older file
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
187 backup_files = [os.path.join(backup_dir, f) for f in os.listdir(backup_dir)]
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
188 if len(backup_files) > unlink_max:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
189 backup_files.sort(key=lambda path: os.stat(path).st_mtime)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
190 for path in backup_files[:len(backup_files) - unlink_max]:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
191 self.host.disp(u"Purging backup file {}".format(path.decode('utf-8')), 2)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
192 os.unlink(path)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
193
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
194 def runEditor(self, editor_args_opt, content_file_path,
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
195 content_file_obj, meta_file_path=None, meta_ori=None):
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
196 """run editor to edit content and metadata
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
197
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
198 @param editor_args_opt(unicode): option in [jp] section in configuration for
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
199 specific args
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
200 @param content_file_path(str): path to the content file
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
201 @param content_file_obj(file): opened file instance
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
202 @param meta_file_path(str, None): metadata file path
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
203 if None metadata will not be used
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
204 @param meta_ori(dict, None): original cotent of metadata
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
205 can't be used if use_metadata is False
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
206 """
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
207 if not self.use_metadata:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
208 assert meta_file_path is None
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
209 assert meta_ori is None
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
210
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
211 # we calculate hashes to check for modifications
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
212 import hashlib
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
213 content_file_obj.seek(0)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
214 tmp_ori_hash = hashlib.sha1(content_file_obj.read()).digest()
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
215 content_file_obj.close()
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
216
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
217 # we prepare arguments
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
218 editor = config.getConfig(self.sat_conf, 'jp', 'editor') or os.getenv('EDITOR', 'vi')
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
219 try:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
220 # is there custom arguments in sat.conf ?
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
221 editor_args = config.getConfig(self.sat_conf, 'jp', editor_args_opt, Exception)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
222 except (NoOptionError, NoSectionError):
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
223 # no, we check if we know the editor and have special arguments
2273
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
224 if self.use_metadata:
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
225 editor_args = EDITOR_ARGS_MAGIC.get(os.path.basename(editor), '')
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
226 else:
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
227 editor_args = ''
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
228 parse_kwargs = {'content_file': content_file_path}
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
229 if self.use_metadata:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
230 parse_kwargs['metadata_file'] = meta_file_path
2273
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
231 args = parse_args(self.host, editor_args, **parse_kwargs)
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
232 if not args:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
233 args = [content_file_path]
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
234
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
235 # actual editing
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
236 editor_exit = subprocess.call([editor] + args)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
237
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
238 # edition will now be checked, and data will be sent if it was a success
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
239 if editor_exit != 0:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
240 self.disp(u"Editor exited with an error code, so temporary file has not be deleted, and item is not published.\nYou can find temporary file at {path}".format(
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
241 path=content_file_path), error=True)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
242 else:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
243 # main content
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
244 try:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
245 with open(content_file_path, 'rb') as f:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
246 content = f.read()
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
247 except (OSError, IOError):
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
248 self.disp(u"Can read file at {content_path}, have it been deleted?\nCancelling edition".format(
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
249 content_path=content_file_path), error=True)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
250 self.host.quit(C.EXIT_NOT_FOUND)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
251
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
252 # metadata
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
253 if self.use_metadata:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
254 try:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
255 with open(meta_file_path, 'rb') as f:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
256 metadata = json.load(f)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
257 except (OSError, IOError):
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
258 self.disp(u"Can read file at {meta_file_path}, have it been deleted?\nCancelling edition".format(
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
259 content_path=content_file_path, meta_path=meta_file_path), error=True)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
260 self.host.quit(C.EXIT_NOT_FOUND)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
261 except ValueError:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
262 self.disp(u"Can't parse metadata, please check it is correct JSON format. Cancelling edition.\n" +
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
263 "You can find tmp file at {content_path} and temporary meta file at {meta_path}.".format(
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
264 content_path=content_file_path,
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
265 meta_path=meta_file_path), error=True)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
266 self.host.quit(C.EXIT_DATA_ERROR)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
267
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
268 if self.use_metadata and not C.bool(metadata.get('publish', "true")):
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
269 self.disp(u'Publication blocked by "publish" key in metadata, cancelling edition.\n\n' +
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
270 "temporary file path:\t{content_path}\nmetadata file path:\t{meta_path}".format(
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
271 content_path=content_file_path, meta_path=meta_file_path), error=True)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
272 self.host.quit()
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
273
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
274 if len(content) == 0:
2273
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
275 self.disp(u"Content is empty, cancelling the edition")
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
276 if not content_file_path.startswith(getTmpDir(self.sat_conf, self.cat_dir_str)):
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
277 self.disp(u"File are not in SàT temporary hierarchy, we do not remove them", 2)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
278 self.host.quit()
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
279 self.disp(u"Deletion of {}".format(content_file_path.decode('utf-8')), 2)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
280 os.unlink(content_file_path)
2273
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
281 if self.use_metadata:
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
282 self.disp(u"Deletion of {}".format(meta_file_path.decode('utf-8')), 2)
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
283 os.unlink(meta_file_path)
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
284 self.host.quit()
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
285
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
286 # time to re-check the hash
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
287 elif (tmp_ori_hash == hashlib.sha1(content).digest() and
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
288 (not self.use_metadata or meta_ori == metadata)):
2273
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
289 self.disp(u"The content has not been modified, cancelling the edition")
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
290 self.host.quit()
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
291
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
292 else:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
293 # we can now send the item
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
294 content = content.decode('utf-8-sig') # we use utf-8-sig to avoid BOM
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
295 try:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
296 if self.use_metadata:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
297 self.publish(content, metadata)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
298 else:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
299 self.publish(content)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
300 except Exception as e:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
301 if self.use_metadata:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
302 self.disp(u"Error while sending your item, the temporary files have been kept at {content_path} and {meta_path}: {reason}".format(
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
303 content_path=content_file_path, meta_path=meta_file_path, reason=e), error=True)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
304 else:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
305 self.disp(u"Error while sending your item, the temporary file has been kept at {content_path}: {reason}".format(
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
306 content_path=content_file_path, reason=e), error=True)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
307 self.host.quit(1)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
308
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
309 self.secureUnlink(content_file_path)
2273
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
310 if self.use_metadata:
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
311 self.secureUnlink(meta_file_path)
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
312
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
313 def publish(self, content):
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
314 # if metadata is needed, publish will be called with it last argument
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
315 raise NotImplementedError
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
316
2351
3c0a3fae1862 jp (pubsub/node): added schema (set/edit/get) commands to manipulate PubSub node schema
Goffi <goffi@goffi.org>
parents: 2345
diff changeset
317 def getTmpFile(self):
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
318 """Create a temporary file
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
319
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
320 @param suff (str): suffix to use for the filename
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
321 @return (tuple(file, str)): opened (w+b) file object and file path
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
322 """
2351
3c0a3fae1862 jp (pubsub/node): added schema (set/edit/get) commands to manipulate PubSub node schema
Goffi <goffi@goffi.org>
parents: 2345
diff changeset
323 suff = '.' + self.getTmpSuff()
2273
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
324 cat_dir_str = self.cat_dir_str
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
325 tmp_dir = getTmpDir(self.sat_conf, self.cat_dir_str, self.profile.encode('utf-8'))
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
326 if not os.path.exists(tmp_dir):
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
327 try:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
328 os.makedirs(tmp_dir)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
329 except OSError as e:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
330 self.disp(u"Can't create {path} directory: {reason}".format(
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
331 path=tmp_dir, reason=e), error=True)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
332 self.host.quit(1)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
333 try:
2273
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
334 fd, path = tempfile.mkstemp(suffix=suff.encode('utf-8'),
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
335 prefix=time.strftime(cat_dir_str + '_%Y-%m-%d_%H:%M:%S_'),
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
336 dir=tmp_dir, text=True)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
337 return os.fdopen(fd, 'w+b'), path
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
338 except OSError as e:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
339 self.disp(u"Can't create temporary file: {reason}".format(reason=e), error=True)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
340 self.host.quit(1)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
341
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
342 def getCurrentFile(self, profile):
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
343 """Get most recently edited file
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
344
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
345 @param profile(unicode): profile linked to the draft
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
346 @return(str): full path of current file
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
347 """
2273
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
348 # we guess the item currently edited by choosing
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
349 # the most recent file corresponding to temp file pattern
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
350 # in tmp_dir, excluding metadata files
2273
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
351 cat_dir_str = self.cat_dir_str
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
352 tmp_dir = getTmpDir(self.sat_conf, self.cat_dir_str, profile.encode('utf-8'))
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
353 available = [path for path in glob.glob(os.path.join(tmp_dir, cat_dir_str + '_*')) if not path.endswith(METADATA_SUFF)]
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
354 if not available:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
355 self.disp(u"Could not find any content draft in {path}".format(path=tmp_dir), error=True)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
356 self.host.quit(1)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
357 return max(available, key=lambda path: os.stat(path).st_mtime)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
358
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
359 def getItemData(self, service, node, item):
2280
4bc9a2c2d6c9 jp (pubsub, common): fixed last item edition (keep item id instead of creating a new one)
Goffi <goffi@goffi.org>
parents: 2279
diff changeset
360 """return formatted content, metadata (or not if use_metadata is false), and item id"""
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
361 raise NotImplementedError
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
362
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
363 def getTmpSuff(self):
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
364 """return suffix used for content file"""
2273
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
365 return u'xml'
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
366
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
367 def getItemPath(self, item):
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
368 """retrieve item path (i.e. service and node) from item argument
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
369
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
370 This method is obviously only useful for edition of PubSub based features
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
371 service, node and item must be named like this in args
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
372 @param item(unicode): item to get or url or magic keyword
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
373 item argument can be used to specify :
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
374 - HTTP(S) URL
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
375 - XMPP URL
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
376 - keyword, which can be:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
377 - new: create new item
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
378 - last: retrieve last published item
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
379 - current: continue current local draft
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
380 - file path
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
381 - item id
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
382 """
2270
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
383 force_item = self.args.force_item
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
384 if force_item and not item:
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
385 self.parser.error(_(u"an item id must be specified if you use --force-item"))
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
386 command = item.lower()
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
387 pubsub_service = self.args.service
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
388 pubsub_node = self.args.node
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
389 pubsub_item = None
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
390
2270
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
391 if not force_item and command not in ('new', 'last', 'current'):
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
392 # we have probably an URL, we try to parse it
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
393 import urlparse
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
394 url = self.args.item
2329
f15b428852a0 jp (common): fixed encoding issue in URLs
Goffi <goffi@goffi.org>
parents: 2306
diff changeset
395 parsed_url = urlparse.urlsplit(url.encode('utf-8'))
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
396 if parsed_url.scheme.startswith('http'):
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
397 self.disp(u"{} URL found, trying to find associated xmpp: URI".format(parsed_url.scheme.upper()),1)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
398 # HTTP URL, we try to find xmpp: links
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
399 try:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
400 from lxml import etree
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
401 except ImportError:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
402 self.disp(u"lxml module must be installed to use http(s) scheme, please install it with \"pip install lxml\"", error=True)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
403 self.host.quit(1)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
404 import urllib2
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
405 parser = etree.HTMLParser()
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
406 try:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
407 root = etree.parse(urllib2.urlopen(url), parser)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
408 except etree.XMLSyntaxError as e:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
409 self.disp(_(u"Can't parse HTML page : {msg}").format(msg=e))
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
410 links = []
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
411 else:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
412 links = root.xpath("//link[@rel='alternate' and starts-with(@href, 'xmpp:')]")
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
413 if not links:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
414 self.disp(u'Could not find alternate "xmpp:" URI, can\'t find associated XMPP PubSub node/item', error=True)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
415 self.host.quit(1)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
416 url = links[0].get('href')
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
417 parsed_url = urlparse.urlsplit(url)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
418
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
419 if parsed_url.scheme == 'xmpp':
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
420 if self.args.service or self.args.node:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
421 self.parser.error(_(u"You can't use URI and --service or --node at the same time"))
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
422
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
423 self.disp(u"XMPP URI used: {}".format(url),2)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
424 # XXX: if we have not xmpp: URI here, we'll take the data as a file path
2329
f15b428852a0 jp (common): fixed encoding issue in URLs
Goffi <goffi@goffi.org>
parents: 2306
diff changeset
425 pubsub_service = parsed_url.path.decode('utf-8')
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
426 pubsub_data = urlparse.parse_qs(parsed_url.query)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
427 try:
2329
f15b428852a0 jp (common): fixed encoding issue in URLs
Goffi <goffi@goffi.org>
parents: 2306
diff changeset
428 pubsub_node = pubsub_data['node'][0].decode('utf-8')
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
429 except KeyError:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
430 self.disp(u'No node found in xmpp: URI, can\'t retrieve item', error=True)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
431 self.host.quit(1)
2334
ca14e1ced3b5 jp (common): fixed decode error when item is not specified
Goffi <goffi@goffi.org>
parents: 2329
diff changeset
432 pubsub_item = pubsub_data.get('item',[None])[0]
ca14e1ced3b5 jp (common): fixed decode error when item is not specified
Goffi <goffi@goffi.org>
parents: 2329
diff changeset
433 if pubsub_item is not None:
ca14e1ced3b5 jp (common): fixed decode error when item is not specified
Goffi <goffi@goffi.org>
parents: 2329
diff changeset
434 pubsub_item = pubsub_item.decode('utf-8')
2276
5cd45a79775b jp (common): added --last-item to take last item when no item id is found/given
Goffi <goffi@goffi.org>
parents: 2273
diff changeset
435 if pubsub_item is None and self.args.last_item:
5cd45a79775b jp (common): added --last-item to take last item when no item id is found/given
Goffi <goffi@goffi.org>
parents: 2273
diff changeset
436 command = 'last'
5cd45a79775b jp (common): added --last-item to take last item when no item id is found/given
Goffi <goffi@goffi.org>
parents: 2273
diff changeset
437 elif pubsub_item is not None:
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
438 command = 'edit' # XXX: edit command is only used internaly, it similar to last, but with the item given in the URL
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
439 else:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
440 command = 'new'
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
441
2306
07deebea71f3 jp (common): fixed the use of --last-item when "-n [node]" is used
Goffi <goffi@goffi.org>
parents: 2298
diff changeset
442 if self.args.last_item:
07deebea71f3 jp (common): fixed the use of --last-item when "-n [node]" is used
Goffi <goffi@goffi.org>
parents: 2298
diff changeset
443 if pubsub_item is None:
07deebea71f3 jp (common): fixed the use of --last-item when "-n [node]" is used
Goffi <goffi@goffi.org>
parents: 2298
diff changeset
444 command = 'last'
07deebea71f3 jp (common): fixed the use of --last-item when "-n [node]" is used
Goffi <goffi@goffi.org>
parents: 2298
diff changeset
445 elif command != 'last':
07deebea71f3 jp (common): fixed the use of --last-item when "-n [node]" is used
Goffi <goffi@goffi.org>
parents: 2298
diff changeset
446 self.parser.error(_(u"--last-item can't be used with a specified item"))
2276
5cd45a79775b jp (common): added --last-item to take last item when no item id is found/given
Goffi <goffi@goffi.org>
parents: 2273
diff changeset
447
2270
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
448 if not force_item and command in ('new', 'last', 'edit'):
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
449 # we need a temporary file
2351
3c0a3fae1862 jp (pubsub/node): added schema (set/edit/get) commands to manipulate PubSub node schema
Goffi <goffi@goffi.org>
parents: 2345
diff changeset
450 content_file_obj, content_file_path = self.getTmpFile()
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
451 if command == 'new':
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
452 self.disp(u'Editing a new item', 2)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
453 if self.use_metadata:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
454 metadata = None
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
455 elif command in ('last', 'edit'):
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
456 self.disp(u'Editing requested published item', 2)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
457 try:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
458 if self.use_metadata:
2280
4bc9a2c2d6c9 jp (pubsub, common): fixed last item edition (keep item id instead of creating a new one)
Goffi <goffi@goffi.org>
parents: 2279
diff changeset
459 content, metadata, pubsub_item = self.getItemData(pubsub_service, pubsub_node, pubsub_item)
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
460 else:
2280
4bc9a2c2d6c9 jp (pubsub, common): fixed last item edition (keep item id instead of creating a new one)
Goffi <goffi@goffi.org>
parents: 2279
diff changeset
461 content, pubsub_item = self.getItemData(pubsub_service, pubsub_node, pubsub_item)
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
462 except Exception as e:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
463 self.disp(u"Error while retrieving last item: {}".format(e))
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
464 self.host.quit(1)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
465 content_file_obj.write(content.encode('utf-8'))
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
466 content_file_obj.seek(0)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
467 else:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
468 if self.use_metadata:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
469 metadata = None
2270
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
470 if not force_item and command == 'current':
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
471 # user wants to continue current draft
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
472 content_file_path = self.getCurrentFile(self.profile)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
473 self.disp(u'Continuing edition of current draft', 2)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
474 content_file_obj = open(content_file_path, 'r+b')
2270
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
475 elif not force_item and os.path.isfile(self.args.item):
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
476 # there is an existing draft that we use
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
477 content_file_path = os.path.expanduser(self.args.item)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
478 content_file_obj = open(content_file_path, 'r+b')
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
479 else:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
480 # last chance, it should be an item
2351
3c0a3fae1862 jp (pubsub/node): added schema (set/edit/get) commands to manipulate PubSub node schema
Goffi <goffi@goffi.org>
parents: 2345
diff changeset
481 content_file_obj, content_file_path = self.getTmpFile()
2270
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
482 pubsub_item = self.args.item
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
483
2270
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
484 try:
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
485 # we try to get existing item
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
486 if self.use_metadata:
2280
4bc9a2c2d6c9 jp (pubsub, common): fixed last item edition (keep item id instead of creating a new one)
Goffi <goffi@goffi.org>
parents: 2279
diff changeset
487 content, metadata, pubsub_item = self.getItemData(pubsub_service, pubsub_node, self.args.item)
2270
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
488 else:
2280
4bc9a2c2d6c9 jp (pubsub, common): fixed last item edition (keep item id instead of creating a new one)
Goffi <goffi@goffi.org>
parents: 2279
diff changeset
489 content, pubsub_item = self.getItemData(pubsub_service, pubsub_node, self.args.item)
2270
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
490 except Exception as e:
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
491 # FIXME: ugly but we have not good may to check errors in bridge
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
492 if u'item-not-found' in unicode(e):
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
493 # item doesn't exist, we create a new one with requested id
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
494 metadata = None
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
495 self.disp(_(u'item "{item_id}" not found, we create a new item with this id').format(item_id=pubsub_item), 2)
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
496 else:
2270
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
497 # item exists, we write content if content file
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
498 content_file_obj.write(content.encode('utf-8'))
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
499 content_file_obj.seek(0)
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
500 self.disp(_(u'item "{item_id}" found, we edit it').format(item_id=pubsub_item), 2)
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
501
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
502 if self.use_metadata:
2270
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
503 return pubsub_service, pubsub_node, pubsub_item, content_file_path, content_file_obj, metadata
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
504 else:
2270
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
505 return pubsub_service, pubsub_node, pubsub_item, content_file_path, content_file_obj
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
506
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
507
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
508 class Table(object):
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
509
2345
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
510 def __init__(self, host, data, headers=None, filters=None, use_buffer=False):
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
511 """
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
512 @param data(list[list]): table data
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
513 all lines must have the same number of columns
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
514 @param headers(iterable[unicode], None): names/titles of the columns
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
515 if not None, must have same number of columns as data
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
516 @param filters(iterable[(callable, unicode)], None): values filters
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
517 the callable will get col value as argument and must return a string
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
518 if it's unicode, it will be used with .format and must countain u'{}' which will be replaced with the string
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
519 if not None, must have same number of columns as data
2345
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
520 @param use_buffer(bool): if True, bufferise output instead of printing it directly
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
521 """
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
522 self.host = host
2345
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
523 self._buffer = [] if use_buffer else None
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
524 # headers are columns names/titles, can be None
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
525 self.headers = headers
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
526 # sizes fof columns without headers,
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
527 # headers may be larger
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
528 self.sizes = []
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
529 # rows countains one list per row with columns values
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
530 self.rows = []
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
531
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
532 size = None
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
533 for line in data:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
534 new_row = []
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
535 for idx, value in enumerate(line):
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
536 if filters is not None and filters[idx] is not None:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
537 filter_ = filters[idx]
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
538 if isinstance(filter_, basestring):
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
539 col_value = filter_.format(value)
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
540 else:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
541 col_value = filter_(value)
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
542 # we count size without ANSI code as they will change length of the string
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
543 # when it's mostly style/color changes.
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
544 col_size = len(regex.ansiRemove(col_value))
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
545 else:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
546 col_value = unicode(value)
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
547 col_size = len(col_value)
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
548 new_row.append(col_value)
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
549 if size is None:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
550 self.sizes.append(col_size)
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
551 else:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
552 self.sizes[idx] = max(self.sizes[idx], col_size)
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
553 if size is None:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
554 size = len(new_row)
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
555 if headers is not None and len(headers) != size:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
556 raise exceptions.DataError(u'headers size is not coherent with rows')
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
557 else:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
558 if len(new_row) != size:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
559 raise exceptions.DataError(u'rows size is not coherent')
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
560 self.rows.append(new_row)
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
561
2344
78ffb9ce57a4 jp (common): fixed empty table display when headers are specified
Goffi <goffi@goffi.org>
parents: 2334
diff changeset
562 if not data and headers is not None:
78ffb9ce57a4 jp (common): fixed empty table display when headers are specified
Goffi <goffi@goffi.org>
parents: 2334
diff changeset
563 # the table is empty, we print headers at their lenght
78ffb9ce57a4 jp (common): fixed empty table display when headers are specified
Goffi <goffi@goffi.org>
parents: 2334
diff changeset
564 self.sizes = [len(h) for h in headers]
78ffb9ce57a4 jp (common): fixed empty table display when headers are specified
Goffi <goffi@goffi.org>
parents: 2334
diff changeset
565
2345
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
566 @property
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
567 def string(self):
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
568 if self._buffer is None:
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
569 raise exceptions.InternalError(u'buffer must be used to get a string')
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
570 return u'\n'.join(self._buffer)
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
571
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
572 @staticmethod
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
573 def readDictValues(data, keys, defaults=None):
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
574 if defaults is None:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
575 defaults = {}
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
576 for key in keys:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
577 try:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
578 yield data[key]
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
579 except KeyError as e:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
580 default = defaults.get(key)
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
581 if default is not None:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
582 yield default
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
583 else:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
584 raise e
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
585
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
586 @classmethod
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
587 def fromDict(cls, host, data, keys=None, headers=None, filters=None, defaults=None):
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
588 """Prepare a table to display it
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
589
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
590 the whole data will be read and kept into memory,
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
591 to be printed
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
592 @param data(list[dict[unicode, unicode]]): data to create the table from
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
593 @param keys(iterable[unicode], None): keys to get
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
594 if None, all keys will be used
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
595 @param headers(iterable[unicode], None): name of the columns
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
596 names must be in same order as keys
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
597 @param filters(dict[unicode, (callable,unicode)), None): filter to use on values
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
598 keys correspond to keys to filter, and value is a callable or unicode which
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
599 will get the value as argument and must return a string
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
600 @param defaults(dict[unicode, unicode]): default value to use
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
601 if None, an exception will be raised if not value is found
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
602 """
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
603 if keys is None and headers is not None:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
604 # FIXME: keys are not needed with OrderedDict,
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
605 raise exceptions.DataError(u'You must specify keys order to used headers')
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
606 if keys is None:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
607 keys = data[0].keys()
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
608 if headers is None:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
609 headers = keys
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
610 filters = [filters.get(k) for k in keys]
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
611 return cls(host, (cls.readDictValues(d, keys, defaults) for d in data), headers, filters)
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
612
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
613 def _headers(self, head_sep, alignment=u'left', style=None):
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
614 """Render headers
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
615
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
616 @param head_sep(unicode): sequence to use as separator
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
617 @param alignment(unicode): how to align, can be left, center or right
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
618 @param style(unicode, iterable[unicode], None): ANSI escape sequences to apply
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
619 """
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
620 headers = []
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
621 if isinstance(style, basestring):
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
622 style = [style]
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
623 for idx, header in enumerate(self.headers):
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
624 size = self.sizes[idx]
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
625 if alignment == u'left':
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
626 rendered = header[:size].ljust(size)
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
627 elif alignment == u'center':
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
628 rendered = header[:size].center(size)
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
629 elif alignment == u'right':
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
630 rendered = header[:size].rjust(size)
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
631 else:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
632 raise exceptions.InternalError(u'bad alignment argument')
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
633 if style:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
634 args = style + [rendered]
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
635 rendered = A.color(*args)
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
636 headers.append(rendered)
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
637 return head_sep.join(headers)
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
638
2345
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
639 def _disp(self, data):
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
640 """output data (can be either bufferised or printed)"""
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
641 if self._buffer is not None:
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
642 self._buffer.append(data)
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
643 else:
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
644 self.host.disp(data)
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
645
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
646 def display(self,
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
647 head_alignment = u'left',
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
648 columns_alignment = u'left',
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
649 head_style = None,
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
650 show_header=True,
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
651 show_borders=True,
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
652 col_sep=u' │ ',
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
653 top_left=u'┌',
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
654 top=u'─',
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
655 top_sep=u'─┬─',
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
656 top_right=u'┐',
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
657 left=u'│',
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
658 right=None,
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
659 head_sep=None,
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
660 head_line=u'┄',
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
661 head_line_left=u'├',
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
662 head_line_sep=u'┄┼┄',
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
663 head_line_right=u'┤',
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
664 bottom_left=u'└',
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
665 bottom=None,
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
666 bottom_sep=u'─┴─',
2345
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
667 bottom_right=u'┘',
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
668 ):
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
669 """Print the table
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
670
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
671 @param show_header(bool): True if header need no be shown
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
672 @param show_borders(bool): True if borders need no be shown
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
673 @param head_alignment(unicode): how to align headers, can be left, center or right
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
674 @param columns_alignment(unicode): how to align columns, can be left, center or right
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
675 @param col_sep(unicode): separator betweens columns
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
676 @param head_line(unicode): character to use to make line under head
2345
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
677 @param disp(callable, None): method to use to display the table
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
678 None to use self.host.disp
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
679 """
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
680 col_sep_size = len(regex.ansiRemove(col_sep))
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
681 if right is None:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
682 right = left
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
683 if top_sep is None:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
684 top_sep = col_sep_size * top
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
685 if head_sep is None:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
686 head_sep = col_sep
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
687 if bottom is None:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
688 bottom = top
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
689 if bottom_sep is None:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
690 bottom_sep = col_sep_size * bottom
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
691 if not show_borders:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
692 left = right = head_line_left = head_line_right = u''
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
693 # top border
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
694 if show_borders:
2345
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
695 self._disp(
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
696 top_left
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
697 + top_sep.join([top*size for size in self.sizes])
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
698 + top_right
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
699 )
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
700
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
701 # headers
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
702 if show_header:
2345
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
703 self._disp(
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
704 left
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
705 + self._headers(head_sep, head_alignment, head_style)
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
706 + right
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
707 )
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
708 # header line
2345
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
709 self._disp(
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
710 head_line_left
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
711 + head_line_sep.join([head_line*size for size in self.sizes])
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
712 + head_line_right
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
713 )
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
714
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
715 # content
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
716 if columns_alignment == u'left':
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
717 alignment = lambda idx, s: ansi_ljust(s, self.sizes[idx])
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
718 elif columns_alignment == u'center':
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
719 alignment = lambda idx, s: ansi_center(s, self.sizes[idx])
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
720 elif columns_alignment == u'right':
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
721 alignment = lambda idx, s: ansi_rjust(s, self.sizes[idx])
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
722 else:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
723 raise exceptions.InternalError(u'bad columns alignment argument')
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
724
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
725 for row in self.rows:
2345
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
726 self._disp(left + col_sep.join([alignment(idx,c) for idx,c in enumerate(row)]) + right)
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
727
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
728 if show_borders:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
729 # bottom border
2345
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
730 self._disp(
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
731 bottom_left
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
732 + bottom_sep.join([bottom*size for size in self.sizes])
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
733 + bottom_right
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
734 )
2345
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
735 # we return self so string can be used after display (table.display().string)
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
736 return self
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
737
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
738 def display_blank(self, **kwargs):
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
739 """Display table without visible borders"""
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
740 kwargs_ = {'col_sep':u' ', 'head_line_sep':u' ', 'show_borders':False}
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
741 kwargs_.update(kwargs)
2345
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
742 return self.display(self,
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
743 **kwargs_
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
744 )