Mercurial > libervia-backend
annotate sat_frontends/jp/common.py @ 3044:691283719bb2
core (patches): updated TLS patches:
- updated patches to handle TLS after implementation in Twisted 19.7.0. A patch is still
needed for Wokkel.
- minimum required version of Twisted is now 19.7.0
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 01 Oct 2019 22:49:10 +0200 |
parents | fee60f17ebac |
children | d9f328374473 |
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 |
2771 | 5 # Copyright (C) 2009-2019 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 |
3040 | 20 import json |
21 import os | |
22 import os.path | |
23 import time | |
24 import tempfile | |
25 import asyncio | |
26 import shlex | |
27 from pathlib import Path | |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
28 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
|
29 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
|
30 from sat.core import exceptions |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
31 from sat.tools.common import regex |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
32 from sat.tools.common.ansi import ANSI as A |
2551
b27165bf160c
jp (merge-request/set): if service and node are not specified, URIFinder is now used + ask confirmation before publishing
Goffi <goffi@goffi.org>
parents:
2532
diff
changeset
|
33 from sat.tools.common import uri as xmpp_uri |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
34 from sat.tools import config |
3028 | 35 from configparser import NoSectionError, NoOptionError |
2493
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
36 from collections import namedtuple |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
37 |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
38 # defaut arguments used for some known editors (editing with metadata) |
2523
21d43eab3fb9
jp (common): assure nosplitright in default commands for edition with vim
Goffi <goffi@goffi.org>
parents:
2493
diff
changeset
|
39 VIM_SPLIT_ARGS = "-c 'set nospr|vsplit|wincmd w|next|wincmd w'" |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
40 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
|
41 EDITOR_ARGS_MAGIC = { |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
42 "vim": VIM_SPLIT_ARGS + " {content_file} {metadata_file}", |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
43 "gvim": VIM_SPLIT_ARGS + " --nofork {content_file} {metadata_file}", |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
44 "emacs": EMACS_SPLIT_ARGS + " {content_file} {metadata_file}", |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
45 "xemacs": EMACS_SPLIT_ARGS + " {content_file} {metadata_file}", |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
46 "nano": " -F {content_file} {metadata_file}", |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
47 } |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
48 |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
49 SECURE_UNLINK_MAX = 10 |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
50 SECURE_UNLINK_DIR = ".backup" |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
51 METADATA_SUFF = "_metadata.json" |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
52 |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
53 |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
54 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
|
55 """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
|
56 cleaned = regex.ansiRemove(s) |
3028 | 57 return s + " " * (width - len(cleaned)) |
2298
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 |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
60 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
|
61 """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
|
62 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
|
63 diff = width - len(cleaned) |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
64 half = diff / 2 |
3028 | 65 return half * " " + s + (half + diff % 2) * " " |
2298
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 |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
68 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
|
69 """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
|
70 cleaned = regex.ansiRemove(s) |
3028 | 71 return " " * (width - len(cleaned)) + s |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
72 |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
73 |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
74 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
|
75 """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
|
76 |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
77 @param sat_conf(ConfigParser.ConfigParser): instance opened on sat configuration |
3040 | 78 @param cat_dir(str): 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
|
79 @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
|
80 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
|
81 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
|
82 initial str) |
3040 | 83 @return (Path): path to the dir |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
84 """ |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
85 local_dir = config.getConfig(sat_conf, "", "local_dir", Exception) |
3040 | 86 path_elts = [local_dir, cat_dir] |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
87 if sub_dir is not None: |
3040 | 88 path_elts.append(regex.pathEscape(sub_dir)) |
89 return Path(*path_elts) | |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
90 |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
91 |
2273
5f0dbf42aa9c
jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents:
2270
diff
changeset
|
92 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
|
93 """Parse command arguments |
5f0dbf42aa9c
jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents:
2270
diff
changeset
|
94 |
5f0dbf42aa9c
jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents:
2270
diff
changeset
|
95 @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
|
96 @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
|
97 @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
|
98 """ |
5f0dbf42aa9c
jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents:
2270
diff
changeset
|
99 try: |
5f0dbf42aa9c
jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents:
2270
diff
changeset
|
100 # 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
|
101 # 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
|
102 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
|
103 except ValueError as e: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
104 host.disp( |
3028 | 105 "Couldn't parse editor cmd [{cmd}]: {reason}".format(cmd=cmd_line, reason=e) |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
106 ) |
2273
5f0dbf42aa9c
jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents:
2270
diff
changeset
|
107 return [] |
5f0dbf42aa9c
jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents:
2270
diff
changeset
|
108 |
5f0dbf42aa9c
jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents:
2270
diff
changeset
|
109 |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
110 class BaseEdit(object): |
3028 | 111 """base class for editing commands |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
112 |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
113 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
|
114 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
|
115 """ |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
116 |
2273
5f0dbf42aa9c
jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents:
2270
diff
changeset
|
117 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
|
118 """ |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
119 @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
|
120 @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
|
121 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
|
122 @param use_metadata(bool): True is edition need a second file for metadata |
3040 | 123 most of signature change with use_metadata with an additional metadata |
124 argument. | |
125 This is done to raise error if a command needs metadata but forget the flag, | |
126 and vice versa | |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
127 """ |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
128 self.host = host |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
129 self.sat_conf = config.parseMainConf() |
3040 | 130 self.cat_dir = cat_dir |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
131 self.use_metadata = use_metadata |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
132 |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
133 def secureUnlink(self, path): |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
134 """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
|
135 |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
136 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
|
137 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
|
138 older file are deleted |
3040 | 139 @param path(Path, str): file to unlink |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
140 """ |
3040 | 141 path = Path(path).resolve() |
142 if not path.is_file: | |
3028 | 143 raise OSError("path must link to a regular file") |
3040 | 144 if path.parent != getTmpDir(self.sat_conf, self.cat_dir): |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
145 self.disp( |
3040 | 146 f"File {path} is not in SàT temporary hierarchy, we do not remove " |
147 f"it", | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
148 2, |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
149 ) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
150 return |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
151 # 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
|
152 unlink_max = SECURE_UNLINK_MAX * 2 if self.use_metadata else SECURE_UNLINK_MAX |
3040 | 153 backup_dir = getTmpDir(self.sat_conf, self.cat_dir, SECURE_UNLINK_DIR) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
154 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
|
155 os.makedirs(backup_dir) |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
156 filename = os.path.basename(path) |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
157 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
|
158 # we move file to backup dir |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
159 self.host.disp( |
3028 | 160 "Backuping file {src} to {dst}".format( |
161 src=path, dst=backup_path | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
162 ), |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
163 1, |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
164 ) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
165 os.rename(path, backup_path) |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
166 # 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
|
167 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
|
168 if len(backup_files) > unlink_max: |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
169 backup_files.sort(key=lambda path: os.stat(path).st_mtime) |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
170 for path in backup_files[: len(backup_files) - unlink_max]: |
3028 | 171 self.host.disp("Purging backup file {}".format(path), 2) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
172 os.unlink(path) |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
173 |
3040 | 174 async def runEditor(self, editor_args_opt, content_file_path, content_file_obj, |
175 meta_file_path=None, meta_ori=None): | |
176 """Run editor to edit content and metadata | |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
177 |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
178 @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
|
179 specific args |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
180 @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
|
181 @param content_file_obj(file): opened file instance |
3040 | 182 @param meta_file_path(str, Path, None): metadata file path |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
183 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
|
184 @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
|
185 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
|
186 """ |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
187 if not self.use_metadata: |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
188 assert meta_file_path is None |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
189 assert meta_ori is None |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
190 |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
191 # 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
|
192 import hashlib |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
193 |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
194 content_file_obj.seek(0) |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
195 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
|
196 content_file_obj.close() |
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 # we prepare arguments |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
199 editor = config.getConfig(self.sat_conf, "jp", "editor") or os.getenv( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
200 "EDITOR", "vi" |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
201 ) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
202 try: |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
203 # is there custom arguments in sat.conf ? |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
204 editor_args = config.getConfig( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
205 self.sat_conf, "jp", editor_args_opt, Exception |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
206 ) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
207 except (NoOptionError, NoSectionError): |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
208 # 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
|
209 if self.use_metadata: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
210 editor_args = EDITOR_ARGS_MAGIC.get(os.path.basename(editor), "") |
2273
5f0dbf42aa9c
jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents:
2270
diff
changeset
|
211 else: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
212 editor_args = "" |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
213 parse_kwargs = {"content_file": content_file_path} |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
214 if self.use_metadata: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
215 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
|
216 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
|
217 if not args: |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
218 args = [content_file_path] |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
219 |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
220 # actual editing |
3040 | 221 editor_process = await asyncio.create_subprocess_exec( |
222 editor, *[str(a) for a in args]) | |
223 editor_exit = await editor_process.wait() | |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
224 |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
225 # 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
|
226 if editor_exit != 0: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
227 self.disp( |
3040 | 228 f"Editor exited with an error code, so temporary file has not be " |
229 f"deleted, and item is not published.\nYou can find temporary file " | |
230 f"at {content_file_path}", | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
231 error=True, |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
232 ) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
233 else: |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
234 # main content |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
235 try: |
3040 | 236 with content_file_path.open("rb") as f: |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
237 content = f.read() |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
238 except (OSError, IOError): |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
239 self.disp( |
3040 | 240 f"Can read file at {content_file_path}, have it been deleted?\n" |
241 f"Cancelling edition", | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
242 error=True, |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
243 ) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
244 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
|
245 |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
246 # metadata |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
247 if self.use_metadata: |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
248 try: |
3040 | 249 with meta_file_path.open("rb") as f: |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
250 metadata = json.load(f) |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
251 except (OSError, IOError): |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
252 self.disp( |
3040 | 253 f"Can read file at {meta_file_path}, have it been deleted?\n" |
254 f"Cancelling edition", | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
255 error=True, |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
256 ) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
257 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
|
258 except ValueError: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
259 self.disp( |
3040 | 260 f"Can't parse metadata, please check it is correct JSON format. " |
261 f"Cancelling edition.\nYou can find tmp file at " | |
262 f"{content_file_path} and temporary meta file at " | |
263 f"{meta_file_path}.", | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
264 error=True, |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
265 ) |
2269
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 |
2905
d9491cb81726
jp (common): `publish` is now a boolean
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
268 if self.use_metadata and not metadata.get("publish", True): |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
269 self.disp( |
3040 | 270 f'Publication blocked by "publish" key in metadata, cancelling ' |
271 f'edition.\n\ntemporary file path:\t{content_file_path}\nmetadata ' | |
272 f'file path:\t{meta_file_path}', | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
273 error=True, |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
274 ) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
275 self.host.quit() |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
276 |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
277 if len(content) == 0: |
3028 | 278 self.disp("Content is empty, cancelling the edition") |
3040 | 279 if content_file_path.parent != getTmpDir(self.sat_conf, self.cat_dir): |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
280 self.disp( |
3028 | 281 "File are not in SàT temporary hierarchy, we do not remove them", |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
282 2, |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
283 ) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
284 self.host.quit() |
3040 | 285 self.disp(f"Deletion of {content_file_path}", 2) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
286 os.unlink(content_file_path) |
2273
5f0dbf42aa9c
jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents:
2270
diff
changeset
|
287 if self.use_metadata: |
3040 | 288 self.disp(f"Deletion of {meta_file_path}".format(meta_file_path), 2) |
2273
5f0dbf42aa9c
jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents:
2270
diff
changeset
|
289 os.unlink(meta_file_path) |
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 # time to re-check the hash |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
293 elif tmp_ori_hash == hashlib.sha1(content).digest() and ( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
294 not self.use_metadata or meta_ori == metadata |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
295 ): |
3028 | 296 self.disp("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
|
297 self.host.quit() |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
298 |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
299 else: |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
300 # we can now send the item |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
301 content = content.decode("utf-8-sig") # we use utf-8-sig to avoid BOM |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
302 try: |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
303 if self.use_metadata: |
3040 | 304 await self.publish(content, metadata) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
305 else: |
3040 | 306 await self.publish(content) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
307 except Exception as e: |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
308 if self.use_metadata: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
309 self.disp( |
3040 | 310 f"Error while sending your item, the temporary files have " |
311 f"been kept at {content_file_path} and {meta_file_path}: " | |
312 f"{e}", | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
313 error=True, |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
314 ) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
315 else: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
316 self.disp( |
3040 | 317 f"Error while sending your item, the temporary file has been " |
318 f"kept at {content_file_path}: {e}", | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
319 error=True, |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
320 ) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
321 self.host.quit(1) |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
322 |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
323 self.secureUnlink(content_file_path) |
2273
5f0dbf42aa9c
jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents:
2270
diff
changeset
|
324 if self.use_metadata: |
5f0dbf42aa9c
jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents:
2270
diff
changeset
|
325 self.secureUnlink(meta_file_path) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
326 |
3040 | 327 async def publish(self, content): |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
328 # 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
|
329 raise NotImplementedError |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
330 |
2351
3c0a3fae1862
jp (pubsub/node): added schema (set/edit/get) commands to manipulate PubSub node schema
Goffi <goffi@goffi.org>
parents:
2345
diff
changeset
|
331 def getTmpFile(self): |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
332 """Create a temporary file |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
333 |
3040 | 334 @return (tuple(file, Path)): opened (w+b) file object and file path |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
335 """ |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
336 suff = "." + self.getTmpSuff() |
3040 | 337 cat_dir_str = self.cat_dir |
338 tmp_dir = getTmpDir(self.sat_conf, self.cat_dir, self.profile) | |
339 if not tmp_dir.exists(): | |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
340 try: |
3040 | 341 tmp_dir.mkdir(parents=True) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
342 except OSError as e: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
343 self.disp( |
3040 | 344 f"Can't create {tmp_dir} directory: {e}", |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
345 error=True, |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
346 ) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
347 self.host.quit(1) |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
348 try: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
349 fd, path = tempfile.mkstemp( |
3040 | 350 suffix=suff, |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
351 prefix=time.strftime(cat_dir_str + "_%Y-%m-%d_%H:%M:%S_"), |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
352 dir=tmp_dir, |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
353 text=True, |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
354 ) |
3040 | 355 return os.fdopen(fd, "w+b"), Path(path) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
356 except OSError as e: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
357 self.disp( |
3040 | 358 f"Can't create temporary file: {e}", error=True |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
359 ) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
360 self.host.quit(1) |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
361 |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
362 def getCurrentFile(self, profile): |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
363 """Get most recently edited file |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
364 |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
365 @param profile(unicode): profile linked to the draft |
3040 | 366 @return(Path): full path of current file |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
367 """ |
2273
5f0dbf42aa9c
jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents:
2270
diff
changeset
|
368 # 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
|
369 # 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
|
370 # in tmp_dir, excluding metadata files |
3040 | 371 tmp_dir = getTmpDir(self.sat_conf, self.cat_dir, profile) |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
372 available = [ |
3040 | 373 p |
374 for p in tmp_dir.glob(f'{self.cat_dir}_*') | |
375 if not p.match(f"*{METADATA_SUFF}") | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
376 ] |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
377 if not available: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
378 self.disp( |
3040 | 379 f"Could not find any content draft in {tmp_dir}", |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
380 error=True, |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
381 ) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
382 self.host.quit(1) |
3040 | 383 return max(available, key=lambda p: p.stat().st_mtime) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
384 |
3040 | 385 async 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
|
386 """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
|
387 raise NotImplementedError |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
388 |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
389 def getTmpSuff(self): |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
390 """return suffix used for content file""" |
3028 | 391 return "xml" |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
392 |
3040 | 393 async def getItemPath(self): |
394 """Retrieve item path (i.e. service and node) from item argument | |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
395 |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
396 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
|
397 """ |
2532 | 398 service = self.args.service |
399 node = self.args.node | |
400 item = self.args.item | |
401 last_item = self.args.last_item | |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
402 |
2532 | 403 if self.args.current: |
404 # user wants to continue current draft | |
405 content_file_path = self.getCurrentFile(self.profile) | |
3028 | 406 self.disp("Continuing edition of current draft", 2) |
3040 | 407 content_file_obj = content_file_path.open("r+b") |
2532 | 408 # we seek at the end of file in case of an item already exist |
409 # this will write content of the existing item at the end of the draft. | |
410 # This way no data should be lost. | |
411 content_file_obj.seek(0, os.SEEK_END) | |
412 elif self.args.draft_path: | |
413 # there is an existing draft that we use | |
3040 | 414 content_file_path = self.args.draft_path.expanduser() |
415 content_file_obj = content_file_path.open("r+b") | |
2532 | 416 # we seek at the end for the same reason as above |
417 content_file_obj.seek(0, os.SEEK_END) | |
418 else: | |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
419 # 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
|
420 content_file_obj, content_file_path = self.getTmpFile() |
2532 | 421 |
422 if item or last_item: | |
3028 | 423 self.disp("Editing requested published item", 2) |
2532 | 424 try: |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
425 if self.use_metadata: |
3040 | 426 content, metadata, item = await self.getItemData(service, node, item) |
2532 | 427 else: |
3040 | 428 content, item = await self.getItemData(service, node, item) |
2532 | 429 except Exception as e: |
430 # FIXME: ugly but we have not good may to check errors in bridge | |
3028 | 431 if "item-not-found" in str(e): |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
432 # item doesn't exist, we create a new one with requested id |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
433 metadata = None |
2532 | 434 if last_item: |
3028 | 435 self.disp(_("no item found at all, we create a new one"), 2) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
436 else: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
437 self.disp( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
438 _( |
3040 | 439 f'item "{item}" not found, we create a new item with' |
440 f'this id' | |
441 ), | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
442 2, |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
443 ) |
2532 | 444 content_file_obj.seek(0) |
445 else: | |
3040 | 446 self.disp(f"Error while retrieving item: {e}") |
2532 | 447 self.host.quit(C.EXIT_ERROR) |
448 else: | |
449 # item exists, we write content | |
450 if content_file_obj.tell() != 0: | |
451 # we already have a draft, | |
452 # we copy item content after it and add an indicator | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
453 content_file_obj.write("\n*****\n") |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
454 content_file_obj.write(content.encode("utf-8")) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
455 content_file_obj.seek(0) |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
456 self.disp( |
3040 | 457 _(f'item "{item}" found, we edit it'), 2 |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
458 ) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
459 else: |
3028 | 460 self.disp("Editing a new item", 2) |
2269
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
461 if self.use_metadata: |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
462 metadata = None |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
463 |
606ff34d30f2
jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
464 if self.use_metadata: |
2532 | 465 return service, node, 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
|
466 else: |
2532 | 467 return service, node, 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
|
468 |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
469 |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
470 class Table(object): |
2345
c57bc0fe17d9
jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents:
2344
diff
changeset
|
471 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
|
472 """ |
2493
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
473 @param data(iterable[list]): table data |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
474 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
|
475 @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
|
476 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
|
477 @param filters(iterable[(callable, unicode)], None): values filters |
2610
c9dddf691d7b
jp (common): allow tables filters callbacks to have only one argument
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
478 the callable will get 2 arguments: |
c9dddf691d7b
jp (common): allow tables filters callbacks to have only one argument
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
479 - current column value |
c9dddf691d7b
jp (common): allow tables filters callbacks to have only one argument
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
480 - RowData with all columns values |
c9dddf691d7b
jp (common): allow tables filters callbacks to have only one argument
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
481 if may also only use 1 argument, which will then be current col value. |
c9dddf691d7b
jp (common): allow tables filters callbacks to have only one argument
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
482 the callable must return a string |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
483 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
|
484 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
|
485 @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
|
486 """ |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
487 self.host = host |
2345
c57bc0fe17d9
jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents:
2344
diff
changeset
|
488 self._buffer = [] if use_buffer else None |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
489 # headers are columns names/titles, can be None |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
490 self.headers = headers |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
491 # sizes fof columns without headers, |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
492 # 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
|
493 self.sizes = [] |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
494 # rows countains one list per row with columns values |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
495 self.rows = [] |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
496 |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
497 size = None |
2493
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
498 if headers: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
499 row_cls = namedtuple("RowData", headers) |
2493
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
500 else: |
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
501 row_cls = tuple |
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
502 |
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
503 for row_data in data: |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
504 new_row = [] |
2493
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
505 row_data_list = list(row_data) |
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
506 for idx, value in enumerate(row_data_list): |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
507 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
|
508 filter_ = filters[idx] |
3028 | 509 if isinstance(filter_, str): |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
510 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
|
511 else: |
2610
c9dddf691d7b
jp (common): allow tables filters callbacks to have only one argument
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
512 try: |
c9dddf691d7b
jp (common): allow tables filters callbacks to have only one argument
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
513 col_value = filter_(value, row_cls(*row_data_list)) |
c9dddf691d7b
jp (common): allow tables filters callbacks to have only one argument
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
514 except TypeError: |
c9dddf691d7b
jp (common): allow tables filters callbacks to have only one argument
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
515 col_value = filter_(value) |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
516 # 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
|
517 # 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
|
518 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
|
519 else: |
3028 | 520 col_value = str(value) |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
521 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
|
522 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
|
523 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
|
524 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
|
525 else: |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
526 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
|
527 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
|
528 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
|
529 if headers is not None and len(headers) != size: |
3028 | 530 raise exceptions.DataError("headers size is not coherent with rows") |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
531 else: |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
532 if len(new_row) != size: |
3028 | 533 raise exceptions.DataError("rows size is not coherent") |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
534 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
|
535 |
2344
78ffb9ce57a4
jp (common): fixed empty table display when headers are specified
Goffi <goffi@goffi.org>
parents:
2334
diff
changeset
|
536 if not data and headers is not None: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
537 # the table is empty, we print headers at their lenght |
2344
78ffb9ce57a4
jp (common): fixed empty table display when headers are specified
Goffi <goffi@goffi.org>
parents:
2334
diff
changeset
|
538 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
|
539 |
2345
c57bc0fe17d9
jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents:
2344
diff
changeset
|
540 @property |
c57bc0fe17d9
jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents:
2344
diff
changeset
|
541 def string(self): |
c57bc0fe17d9
jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents:
2344
diff
changeset
|
542 if self._buffer is None: |
3028 | 543 raise exceptions.InternalError("buffer must be used to get a string") |
544 return "\n".join(self._buffer) | |
2345
c57bc0fe17d9
jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents:
2344
diff
changeset
|
545 |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
546 @staticmethod |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
547 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
|
548 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
|
549 defaults = {} |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
550 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
|
551 try: |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
552 yield data[key] |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
553 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
|
554 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
|
555 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
|
556 yield default |
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 raise e |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
559 |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
560 @classmethod |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
561 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
|
562 """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
|
563 |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
564 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
|
565 to be printed |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
566 @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
|
567 @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
|
568 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
|
569 @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
|
570 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
|
571 @param filters(dict[unicode, (callable,unicode)), None): filter to use on values |
2610
c9dddf691d7b
jp (common): allow tables filters callbacks to have only one argument
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
572 keys correspond to keys to filter, and value is the same as for Table.__init__ |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
573 @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
|
574 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
|
575 """ |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
576 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
|
577 # FIXME: keys are not needed with OrderedDict, |
3028 | 578 raise exceptions.DataError("You must specify keys order to used headers") |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
579 if keys is None: |
3028 | 580 keys = list(data[0].keys()) |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
581 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
|
582 headers = keys |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
583 filters = [filters.get(k) for k in keys] |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
584 return cls( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
585 host, (cls.readDictValues(d, keys, defaults) for d in data), headers, filters |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
586 ) |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
587 |
3028 | 588 def _headers(self, head_sep, headers, sizes, alignment="left", style=None): |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
589 """Render headers |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
590 |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
591 @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
|
592 @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
|
593 @param style(unicode, iterable[unicode], None): ANSI escape sequences to apply |
2493
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
594 @param headers(list[unicode]): headers to show |
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
595 @param sizes(list[int]): sizes of columns |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
596 """ |
2493
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
597 rendered_headers = [] |
3028 | 598 if isinstance(style, str): |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
599 style = [style] |
2493
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
600 for idx, header in enumerate(headers): |
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
601 size = sizes[idx] |
3028 | 602 if alignment == "left": |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
603 rendered = header[:size].ljust(size) |
3028 | 604 elif alignment == "center": |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
605 rendered = header[:size].center(size) |
3028 | 606 elif alignment == "right": |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
607 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
|
608 else: |
3028 | 609 raise exceptions.InternalError("bad alignment argument") |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
610 if style: |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
611 args = style + [rendered] |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
612 rendered = A.color(*args) |
2493
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
613 rendered_headers.append(rendered) |
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
614 return head_sep.join(rendered_headers) |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
615 |
2345
c57bc0fe17d9
jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents:
2344
diff
changeset
|
616 def _disp(self, data): |
c57bc0fe17d9
jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents:
2344
diff
changeset
|
617 """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
|
618 if self._buffer is not None: |
c57bc0fe17d9
jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents:
2344
diff
changeset
|
619 self._buffer.append(data) |
c57bc0fe17d9
jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents:
2344
diff
changeset
|
620 else: |
c57bc0fe17d9
jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents:
2344
diff
changeset
|
621 self.host.disp(data) |
c57bc0fe17d9
jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents:
2344
diff
changeset
|
622 |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
623 def display( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
624 self, |
3028 | 625 head_alignment="left", |
626 columns_alignment="left", | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
627 head_style=None, |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
628 show_header=True, |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
629 show_borders=True, |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
630 hide_cols=None, |
3028 | 631 col_sep=" │ ", |
632 top_left="┌", | |
633 top="─", | |
634 top_sep="─┬─", | |
635 top_right="┐", | |
636 left="│", | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
637 right=None, |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
638 head_sep=None, |
3028 | 639 head_line="┄", |
640 head_line_left="├", | |
641 head_line_sep="┄┼┄", | |
642 head_line_right="┤", | |
643 bottom_left="└", | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
644 bottom=None, |
3028 | 645 bottom_sep="─┴─", |
646 bottom_right="┘", | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
647 ): |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
648 """Print the table |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
649 |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
650 @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
|
651 @param show_borders(bool): True if borders need no be shown |
2493
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
652 @param hide_cols(None, iterable(unicode)): columns which should not be displayed |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
653 @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
|
654 @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
|
655 @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
|
656 @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
|
657 @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
|
658 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
|
659 """ |
2493
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
660 if not self.sizes: |
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
661 # the table is empty |
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
662 return |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
663 col_sep_size = len(regex.ansiRemove(col_sep)) |
2493
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
664 |
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
665 # if we have columns to hide, we remove them from headers and size |
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
666 if not hide_cols: |
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
667 headers = self.headers |
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
668 sizes = self.sizes |
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
669 else: |
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
670 headers = list(self.headers) |
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
671 sizes = self.sizes[:] |
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
672 ignore_idx = [headers.index(to_hide) for to_hide in hide_cols] |
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
673 for to_hide in hide_cols: |
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
674 hide_idx = headers.index(to_hide) |
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
675 del headers[hide_idx] |
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
676 del sizes[hide_idx] |
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
677 |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
678 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
|
679 right = left |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
680 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
|
681 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
|
682 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
|
683 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
|
684 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
|
685 bottom = top |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
686 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
|
687 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
|
688 if not show_borders: |
3028 | 689 left = right = head_line_left = head_line_right = "" |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
690 # top border |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
691 if show_borders: |
2345
c57bc0fe17d9
jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents:
2344
diff
changeset
|
692 self._disp( |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
693 top_left + top_sep.join([top * size for size in sizes]) + top_right |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
694 ) |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
695 |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
696 # headers |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
697 if show_header: |
2345
c57bc0fe17d9
jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents:
2344
diff
changeset
|
698 self._disp( |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
699 left |
2493
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
700 + self._headers(head_sep, headers, sizes, head_alignment, head_style) |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
701 + right |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
702 ) |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
703 # header line |
2345
c57bc0fe17d9
jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents:
2344
diff
changeset
|
704 self._disp( |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
705 head_line_left |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
706 + head_line_sep.join([head_line * size for size in sizes]) |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
707 + head_line_right |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
708 ) |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
709 |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
710 # content |
3028 | 711 if columns_alignment == "left": |
2493
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
712 alignment = lambda idx, s: ansi_ljust(s, sizes[idx]) |
3028 | 713 elif columns_alignment == "center": |
2493
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
714 alignment = lambda idx, s: ansi_center(s, sizes[idx]) |
3028 | 715 elif columns_alignment == "right": |
2493
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
716 alignment = lambda idx, s: ansi_rjust(s, sizes[idx]) |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
717 else: |
3028 | 718 raise exceptions.InternalError("bad columns alignment argument") |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
719 |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
720 for row in self.rows: |
2493
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
721 if hide_cols: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
722 row = [v for idx, v in enumerate(row) if idx not in ignore_idx] |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
723 self._disp( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
724 left |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
725 + col_sep.join([alignment(idx, c) for idx, c in enumerate(row)]) |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
726 + right |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
727 ) |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
728 |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
729 if show_borders: |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
730 # bottom border |
2345
c57bc0fe17d9
jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents:
2344
diff
changeset
|
731 self._disp( |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
732 bottom_left |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
733 + bottom_sep.join([bottom * size for size in sizes]) |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
734 + bottom_right |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
735 ) |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2610
diff
changeset
|
736 # we return self so string can be used after display (table.display().string) |
2345
c57bc0fe17d9
jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents:
2344
diff
changeset
|
737 return self |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
738 |
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
739 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
|
740 """Display table without visible borders""" |
3028 | 741 kwargs_ = {"col_sep": " ", "head_line_sep": " ", "show_borders": False} |
2298
276e546b7619
jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents:
2280
diff
changeset
|
742 kwargs_.update(kwargs) |
2493
984792a451bc
jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
743 return self.display(**kwargs_) |
2551
b27165bf160c
jp (merge-request/set): if service and node are not specified, URIFinder is now used + ask confirmation before publishing
Goffi <goffi@goffi.org>
parents:
2532
diff
changeset
|
744 |
b27165bf160c
jp (merge-request/set): if service and node are not specified, URIFinder is now used + ask confirmation before publishing
Goffi <goffi@goffi.org>
parents:
2532
diff
changeset
|
745 |
3040 | 746 async def fill_well_known_uri(command, path, key, meta_map=None): |
747 """Look for URIs in well-known location and fill appropriate args if suitable | |
748 | |
749 @param command(CommandBase): command instance | |
750 args of this instance will be updated with found values | |
751 @param path(unicode): absolute path to use as a starting point to look for URIs | |
752 @param key(unicode): key to look for | |
753 @param meta_map(dict, None): if not None, map metadata to arg name | |
754 key is metadata used attribute name | |
755 value is name to actually use, or None to ignore | |
756 use empty dict to only retrieve URI | |
757 possible keys are currently: | |
758 - labels | |
759 """ | |
760 args = command.args | |
761 if args.service or args.node: | |
762 # we only look for URIs if a service and a node are not already specified | |
763 return | |
764 | |
765 host = command.host | |
2551
b27165bf160c
jp (merge-request/set): if service and node are not specified, URIFinder is now used + ask confirmation before publishing
Goffi <goffi@goffi.org>
parents:
2532
diff
changeset
|
766 |
3040 | 767 try: |
768 uris_data = await host.bridge.URIFind(path, [key]) | |
769 except Exception as e: | |
770 host.disp(f"can't find {key} URI: {e}", error=True) | |
771 host.quit(C.EXIT_BRIDGE_ERRBACK) | |
2551
b27165bf160c
jp (merge-request/set): if service and node are not specified, URIFinder is now used + ask confirmation before publishing
Goffi <goffi@goffi.org>
parents:
2532
diff
changeset
|
772 |
3040 | 773 try: |
774 uri_data = uris_data[key] | |
775 except KeyError: | |
776 host.disp( | |
777 _(f"No {key} URI specified for this project, please specify service and " | |
778 f"node"), | |
779 error=True, | |
780 ) | |
781 host.quit(C.EXIT_NOT_FOUND) | |
2558
501b0f827f63
jp (merge-request,common): fixed URIFinder when metadata are not needed:
Goffi <goffi@goffi.org>
parents:
2554
diff
changeset
|
782 |
3040 | 783 uri = uri_data["uri"] |
784 | |
785 # set extra metadata if they are specified | |
786 for data_key in ['labels']: | |
787 new_values_json = uri_data.get(data_key) | |
2558
501b0f827f63
jp (merge-request,common): fixed URIFinder when metadata are not needed:
Goffi <goffi@goffi.org>
parents:
2554
diff
changeset
|
788 if uri_data is not None: |
3040 | 789 if meta_map is None: |
790 dest = data_key | |
2558
501b0f827f63
jp (merge-request,common): fixed URIFinder when metadata are not needed:
Goffi <goffi@goffi.org>
parents:
2554
diff
changeset
|
791 else: |
3040 | 792 dest = meta_map.get(data_key) |
2558
501b0f827f63
jp (merge-request,common): fixed URIFinder when metadata are not needed:
Goffi <goffi@goffi.org>
parents:
2554
diff
changeset
|
793 if dest is None: |
3040 | 794 continue |
2558
501b0f827f63
jp (merge-request,common): fixed URIFinder when metadata are not needed:
Goffi <goffi@goffi.org>
parents:
2554
diff
changeset
|
795 |
501b0f827f63
jp (merge-request,common): fixed URIFinder when metadata are not needed:
Goffi <goffi@goffi.org>
parents:
2554
diff
changeset
|
796 try: |
3040 | 797 values = getattr(args, data_key) |
2558
501b0f827f63
jp (merge-request,common): fixed URIFinder when metadata are not needed:
Goffi <goffi@goffi.org>
parents:
2554
diff
changeset
|
798 except AttributeError: |
3040 | 799 raise exceptions.InternalError(f'there is no {data_key!r} arguments') |
2558
501b0f827f63
jp (merge-request,common): fixed URIFinder when metadata are not needed:
Goffi <goffi@goffi.org>
parents:
2554
diff
changeset
|
800 else: |
501b0f827f63
jp (merge-request,common): fixed URIFinder when metadata are not needed:
Goffi <goffi@goffi.org>
parents:
2554
diff
changeset
|
801 if values is None: |
501b0f827f63
jp (merge-request,common): fixed URIFinder when metadata are not needed:
Goffi <goffi@goffi.org>
parents:
2554
diff
changeset
|
802 values = [] |
501b0f827f63
jp (merge-request,common): fixed URIFinder when metadata are not needed:
Goffi <goffi@goffi.org>
parents:
2554
diff
changeset
|
803 values.extend(json.loads(new_values_json)) |
3040 | 804 setattr(args, dest, values) |
2558
501b0f827f63
jp (merge-request,common): fixed URIFinder when metadata are not needed:
Goffi <goffi@goffi.org>
parents:
2554
diff
changeset
|
805 |
3040 | 806 parsed_uri = xmpp_uri.parseXMPPUri(uri) |
807 try: | |
808 args.service = parsed_uri["path"] | |
809 args.node = parsed_uri["node"] | |
810 except KeyError: | |
811 host.disp(_(f"Invalid URI found: {uri}"), error=True) | |
812 host.quit(C.EXIT_DATA_ERROR) |