annotate sat_frontends/jp/common.py @ 3120:0c29155ac68b

core: backend autoconnection: A new Connection/autoconnect_backend param can be set for a profile or component to be started automatically with backend. This is specially useful for components, but can be useful for client profile too (e.g. on Android we need to start profile with backend to get notifications, this part will come with following commits). The new Sqlite.getIndParamValues method allows to retrieve the same parameters for all profiles.
author Goffi <goffi@goffi.org>
date Sat, 25 Jan 2020 21:08:32 +0100
parents d9f328374473
children 040ca99e25fe
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python2
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
2 # -*- coding: utf-8 -*-
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
3
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # jp: a SàT command line tool
2771
003b8b4b56a7 date update
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
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
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
20 import json
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
21 import os
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
22 import os.path
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
23 import time
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
24 import tempfile
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
25 import asyncio
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
26 import shlex
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
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
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
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
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
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
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
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
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
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
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
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
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
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
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
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
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
88 path_elts.append(regex.pathEscape(sub_dir))
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
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
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
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
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
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
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
123 most of signature change with use_metadata with an additional metadata
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
124 argument.
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
125 This is done to raise error if a command needs metadata but forget the flag,
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
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
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
129 self.cat_dir = cat_dir
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
130 self.use_metadata = use_metadata
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
131
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
132 def secureUnlink(self, path):
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
133 """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
134
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
135 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
136 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
137 older file are deleted
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
138 @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
139 """
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
140 path = Path(path).resolve()
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
141 if not path.is_file:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
142 raise OSError("path must link to a regular file")
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
143 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
144 self.disp(
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
145 f"File {path} is not in SàT temporary hierarchy, we do not remove "
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
146 f"it",
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
147 2,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
148 )
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
149 return
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
150 # 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
151 unlink_max = SECURE_UNLINK_MAX * 2 if self.use_metadata else SECURE_UNLINK_MAX
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
152 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
153 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
154 os.makedirs(backup_dir)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
155 filename = os.path.basename(path)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
156 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
157 # we move file to backup dir
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
158 self.host.disp(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
159 "Backuping file {src} to {dst}".format(
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
160 src=path, dst=backup_path
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
161 ),
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
162 1,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
163 )
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
164 os.rename(path, backup_path)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
165 # 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
166 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
167 if len(backup_files) > unlink_max:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
168 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
169 for path in backup_files[: len(backup_files) - unlink_max]:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
170 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
171 os.unlink(path)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
172
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
173 async def runEditor(self, editor_args_opt, content_file_path, content_file_obj,
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
174 meta_file_path=None, meta_ori=None):
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
175 """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
176
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
177 @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
178 specific args
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
179 @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
180 @param content_file_obj(file): opened file instance
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
181 @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
182 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
183 @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
184 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
185 """
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
186 if not self.use_metadata:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
187 assert meta_file_path is None
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
188 assert meta_ori is None
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
189
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
190 # 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
191 import hashlib
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
192
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
193 content_file_obj.seek(0)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
194 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
195 content_file_obj.close()
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
196
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
197 # we prepare arguments
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
198 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
199 "EDITOR", "vi"
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
200 )
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
201 try:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
202 # is there custom arguments in sat.conf ?
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
203 editor_args = config.getConfig(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
204 self.sat_conf, "jp", editor_args_opt, Exception
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
205 )
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
206 except (NoOptionError, NoSectionError):
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
207 # 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
208 if self.use_metadata:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
209 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
210 else:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
211 editor_args = ""
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
212 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
213 if self.use_metadata:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
214 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
215 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
216 if not args:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
217 args = [content_file_path]
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
218
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
219 # actual editing
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
220 editor_process = await asyncio.create_subprocess_exec(
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
221 editor, *[str(a) for a in args])
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
222 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
223
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
224 # 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
225 if editor_exit != 0:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
226 self.disp(
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
227 f"Editor exited with an error code, so temporary file has not be "
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
228 f"deleted, and item is not published.\nYou can find temporary file "
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
229 f"at {content_file_path}",
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
230 error=True,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
231 )
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
232 else:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
233 # main content
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
234 try:
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
235 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
236 content = f.read()
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
237 except (OSError, IOError):
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
238 self.disp(
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
239 f"Can read file at {content_file_path}, have it been deleted?\n"
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
240 f"Cancelling edition",
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
241 error=True,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
242 )
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
243 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
244
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
245 # metadata
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
246 if self.use_metadata:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
247 try:
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
248 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
249 metadata = json.load(f)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
250 except (OSError, IOError):
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
251 self.disp(
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
252 f"Can read file at {meta_file_path}, have it been deleted?\n"
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
253 f"Cancelling edition",
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
254 error=True,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
255 )
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
256 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
257 except ValueError:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
258 self.disp(
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
259 f"Can't parse metadata, please check it is correct JSON format. "
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
260 f"Cancelling edition.\nYou can find tmp file at "
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
261 f"{content_file_path} and temporary meta file at "
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
262 f"{meta_file_path}.",
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
263 error=True,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
264 )
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
265 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
266
2905
d9491cb81726 jp (common): `publish` is now a boolean
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
267 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
268 self.disp(
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
269 f'Publication blocked by "publish" key in metadata, cancelling '
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
270 f'edition.\n\ntemporary file path:\t{content_file_path}\nmetadata '
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
271 f'file path:\t{meta_file_path}',
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
272 error=True,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
273 )
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
274 self.host.quit()
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
275
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
276 if len(content) == 0:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
277 self.disp("Content is empty, cancelling the edition")
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
278 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
279 self.disp(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
280 "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
281 2,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
282 )
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
283 self.host.quit()
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
284 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
285 os.unlink(content_file_path)
2273
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
286 if self.use_metadata:
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
287 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
288 os.unlink(meta_file_path)
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
289 self.host.quit()
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
290
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
291 # time to re-check the hash
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
292 elif tmp_ori_hash == hashlib.sha1(content).digest() and (
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
293 not self.use_metadata or meta_ori == metadata
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
294 ):
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
295 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
296 self.host.quit()
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
297
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
298 else:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
299 # we can now send the item
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
300 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
301 try:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
302 if self.use_metadata:
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
303 await self.publish(content, metadata)
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
304 else:
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
305 await self.publish(content)
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
306 except Exception as e:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
307 if self.use_metadata:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
308 self.disp(
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
309 f"Error while sending your item, the temporary files have "
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
310 f"been kept at {content_file_path} and {meta_file_path}: "
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
311 f"{e}",
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
312 error=True,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
313 )
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
314 else:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
315 self.disp(
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
316 f"Error while sending your item, the temporary file has been "
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
317 f"kept at {content_file_path}: {e}",
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
318 error=True,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
319 )
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
320 self.host.quit(1)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
321
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
322 self.secureUnlink(content_file_path)
2273
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
323 if self.use_metadata:
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
324 self.secureUnlink(meta_file_path)
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
325
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
326 async def publish(self, content):
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
327 # 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
328 raise NotImplementedError
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
329
2351
3c0a3fae1862 jp (pubsub/node): added schema (set/edit/get) commands to manipulate PubSub node schema
Goffi <goffi@goffi.org>
parents: 2345
diff changeset
330 def getTmpFile(self):
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
331 """Create a temporary file
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
332
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
333 @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
334 """
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
335 suff = "." + self.getTmpSuff()
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
336 cat_dir_str = self.cat_dir
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
337 tmp_dir = getTmpDir(self.sat_conf, self.cat_dir, self.profile)
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
338 if not tmp_dir.exists():
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
339 try:
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
340 tmp_dir.mkdir(parents=True)
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
341 except OSError as e:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
342 self.disp(
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
343 f"Can't create {tmp_dir} directory: {e}",
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
344 error=True,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
345 )
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
346 self.host.quit(1)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
347 try:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
348 fd, path = tempfile.mkstemp(
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
349 suffix=suff,
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
350 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
351 dir=tmp_dir,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
352 text=True,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
353 )
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
354 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
355 except OSError as e:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
356 self.disp(
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
357 f"Can't create temporary file: {e}", error=True
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
358 )
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
359 self.host.quit(1)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
360
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
361 def getCurrentFile(self, profile):
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
362 """Get most recently edited file
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
363
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
364 @param profile(unicode): profile linked to the draft
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
365 @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
366 """
2273
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
367 # 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
368 # 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
369 # in tmp_dir, excluding metadata files
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
370 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
371 available = [
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
372 p
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
373 for p in tmp_dir.glob(f'{self.cat_dir}_*')
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
374 if not p.match(f"*{METADATA_SUFF}")
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
375 ]
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
376 if not available:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
377 self.disp(
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
378 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
379 error=True,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
380 )
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
381 self.host.quit(1)
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
382 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
383
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
384 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
385 """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
386 raise NotImplementedError
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
387
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
388 def getTmpSuff(self):
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
389 """return suffix used for content file"""
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
390 return "xml"
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
391
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
392 async def getItemPath(self):
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
393 """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
394
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
395 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
396 """
2532
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
397 service = self.args.service
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
398 node = self.args.node
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
399 item = self.args.item
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
400 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
401
2532
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
402 if self.args.current:
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
403 # user wants to continue current draft
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
404 content_file_path = self.getCurrentFile(self.profile)
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
405 self.disp("Continuing edition of current draft", 2)
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
406 content_file_obj = content_file_path.open("r+b")
2532
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
407 # we seek at the end of file in case of an item already exist
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
408 # this will write content of the existing item at the end of the draft.
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
409 # This way no data should be lost.
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
410 content_file_obj.seek(0, os.SEEK_END)
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
411 elif self.args.draft_path:
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
412 # there is an existing draft that we use
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
413 content_file_path = self.args.draft_path.expanduser()
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
414 content_file_obj = content_file_path.open("r+b")
2532
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
415 # we seek at the end for the same reason as above
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
416 content_file_obj.seek(0, os.SEEK_END)
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
417 else:
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
418 # 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
419 content_file_obj, content_file_path = self.getTmpFile()
2532
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
420
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
421 if item or last_item:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
422 self.disp("Editing requested published item", 2)
2532
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
423 try:
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
424 if self.use_metadata:
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
425 content, metadata, item = await self.getItemData(service, node, item)
2532
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
426 else:
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
427 content, item = await self.getItemData(service, node, item)
2532
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
428 except Exception as e:
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
429 # FIXME: ugly but we have not good may to check errors in bridge
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
430 if "item-not-found" in str(e):
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
431 #  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
432 metadata = None
2532
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
433 if last_item:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
434 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
435 else:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
436 self.disp(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
437 _(
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
438 f'item "{item}" not found, we create a new item with'
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
439 f'this id'
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
440 ),
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
441 2,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
442 )
2532
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
443 content_file_obj.seek(0)
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
444 else:
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
445 self.disp(f"Error while retrieving item: {e}")
2532
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
446 self.host.quit(C.EXIT_ERROR)
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
447 else:
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
448 # item exists, we write content
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
449 if content_file_obj.tell() != 0:
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
450 # we already have a draft,
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
451 # 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
452 content_file_obj.write("\n*****\n")
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
453 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
454 content_file_obj.seek(0)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
455 self.disp(
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
456 _(f'item "{item}" found, we edit it'), 2
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
457 )
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
458 else:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
459 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
460 if self.use_metadata:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
461 metadata = None
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
462
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents:
diff changeset
463 if self.use_metadata:
2532
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
464 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
465 else:
2532
772447ec070f jp: pubsub options refactoring:
Goffi <goffi@goffi.org>
parents: 2523
diff changeset
466 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
467
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 class Table(object):
2345
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
470 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
471 """
2493
984792a451bc jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
472 @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
473 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
474 @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
475 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
476 @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
477 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
478 - current column value
c9dddf691d7b jp (common): allow tables filters callbacks to have only one argument
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
479 - 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
480 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
481 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
482 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
483 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
484 @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
485 """
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
486 self.host = host
2345
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
487 self._buffer = [] if use_buffer else None
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
488 #  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
489 self.headers = headers
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
490 #  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
491 # 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
492 self.sizes = []
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
493 #  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
494 self.rows = []
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
495
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
496 size = None
2493
984792a451bc jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
497 if headers:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
498 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
499 else:
984792a451bc jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
500 row_cls = tuple
984792a451bc jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
501
984792a451bc jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
502 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
503 new_row = []
2493
984792a451bc jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
504 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
505 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
506 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
507 filter_ = filters[idx]
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
508 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
509 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
510 else:
2610
c9dddf691d7b jp (common): allow tables filters callbacks to have only one argument
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
511 try:
c9dddf691d7b jp (common): allow tables filters callbacks to have only one argument
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
512 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
513 except TypeError:
c9dddf691d7b jp (common): allow tables filters callbacks to have only one argument
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
514 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
515 # 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
516 # 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
517 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
518 else:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
519 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
520 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
521 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
522 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
523 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
524 else:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
525 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
526 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
527 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
528 if headers is not None and len(headers) != size:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
529 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
530 else:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
531 if len(new_row) != size:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
532 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
533 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
534
2344
78ffb9ce57a4 jp (common): fixed empty table display when headers are specified
Goffi <goffi@goffi.org>
parents: 2334
diff changeset
535 if not data and headers is not None:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
536 #  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
537 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
538
2345
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
539 @property
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
540 def string(self):
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
541 if self._buffer is None:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
542 raise exceptions.InternalError("buffer must be used to get a string")
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
543 return "\n".join(self._buffer)
2345
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
544
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
545 @staticmethod
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
546 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
547 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
548 defaults = {}
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
549 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
550 try:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
551 yield data[key]
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
552 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
553 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
554 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
555 yield default
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
556 else:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
557 raise e
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
558
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
559 @classmethod
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
560 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
561 """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
562
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
563 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
564 to be printed
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
565 @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
566 @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
567 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
568 @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
569 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
570 @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
571 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
572 @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
573 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
574 """
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
575 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
576 # FIXME: keys are not needed with OrderedDict,
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
577 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
578 if keys is None:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
579 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
580 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
581 headers = keys
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
582 filters = [filters.get(k) for k in keys]
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
583 return cls(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
584 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
585 )
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
586
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
587 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
588 """Render headers
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
589
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
590 @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
591 @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
592 @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
593 @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
594 @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
595 """
2493
984792a451bc jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
596 rendered_headers = []
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
597 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
598 style = [style]
2493
984792a451bc jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
599 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
600 size = sizes[idx]
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
601 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
602 rendered = header[:size].ljust(size)
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
603 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
604 rendered = header[:size].center(size)
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
605 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
606 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
607 else:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
608 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
609 if style:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
610 args = style + [rendered]
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
611 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
612 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
613 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
614
2345
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
615 def _disp(self, data):
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
616 """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
617 if self._buffer is not None:
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
618 self._buffer.append(data)
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
619 else:
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
620 self.host.disp(data)
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
621
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
622 def display(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
623 self,
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
624 head_alignment="left",
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
625 columns_alignment="left",
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
626 head_style=None,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
627 show_header=True,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
628 show_borders=True,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
629 hide_cols=None,
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
630 col_sep=" │ ",
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
631 top_left="┌",
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
632 top="─",
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
633 top_sep="─┬─",
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
634 top_right="┐",
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
635 left="│",
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
636 right=None,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
637 head_sep=None,
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
638 head_line="┄",
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
639 head_line_left="├",
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
640 head_line_sep="┄┼┄",
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
641 head_line_right="┤",
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
642 bottom_left="└",
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
643 bottom=None,
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
644 bottom_sep="─┴─",
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
645 bottom_right="┘",
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
646 ):
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
647 """Print the table
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
648
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
649 @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
650 @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
651 @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
652 @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
653 @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
654 @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
655 @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
656 @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
657 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
658 """
2493
984792a451bc jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
659 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
660 # 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
661 return
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
662 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
663
984792a451bc jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
664 # 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
665 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
666 headers = self.headers
984792a451bc jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
667 sizes = self.sizes
984792a451bc jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
668 else:
984792a451bc jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
669 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
670 sizes = self.sizes[:]
984792a451bc jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
671 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
672 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 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
674 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
675 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
676
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
677 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
678 right = left
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
679 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
680 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
681 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
682 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
683 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
684 bottom = top
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
685 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
686 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
687 if not show_borders:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
688 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
689 # top border
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
690 if show_borders:
2345
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
691 self._disp(
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
692 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
693 )
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
694
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
695 # headers
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
696 if show_header:
2345
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
697 self._disp(
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
698 left
2493
984792a451bc jp (common/table): a column can be hidden + fix for empty tables
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
699 + 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
700 + right
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
701 )
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
702 # header line
2345
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
703 self._disp(
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
704 head_line_left
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
705 + 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
706 + head_line_right
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
707 )
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
708
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
709 # content
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
710 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
711 alignment = lambda idx, s: ansi_ljust(s, sizes[idx])
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
712 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
713 alignment = lambda idx, s: ansi_center(s, sizes[idx])
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
714 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
715 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
716 else:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
717 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
718
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
719 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
720 if hide_cols:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
721 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
722 self._disp(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
723 left
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
724 + 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
725 + right
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
726 )
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
727
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
728 if show_borders:
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
729 # bottom border
2345
c57bc0fe17d9 jp (common): added use_buffer argument in Table:
Goffi <goffi@goffi.org>
parents: 2344
diff changeset
730 self._disp(
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
731 bottom_left
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
732 + 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
733 + bottom_right
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
734 )
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2610
diff changeset
735 #  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
736 return self
2298
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
737
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
738 def display_blank(self, **kwargs):
276e546b7619 jp (common): new ansi_ljust, ansi_rjust and ansi_center command + table:
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
739 """Display table without visible borders"""
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2905
diff changeset
740 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
741 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
742 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
743
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
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
745 async def fill_well_known_uri(command, path, key, meta_map=None):
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
746 """Look for URIs in well-known location and fill appropriate args if suitable
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
747
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
748 @param command(CommandBase): command instance
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
749 args of this instance will be updated with found values
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
750 @param path(unicode): absolute path to use as a starting point to look for URIs
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
751 @param key(unicode): key to look for
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
752 @param meta_map(dict, None): if not None, map metadata to arg name
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
753 key is metadata used attribute name
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
754 value is name to actually use, or None to ignore
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
755 use empty dict to only retrieve URI
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
756 possible keys are currently:
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
757 - labels
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
758 """
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
759 args = command.args
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
760 if args.service or args.node:
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
761 # we only look for URIs if a service and a node are not already specified
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
762 return
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
763
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
764 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
765
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
766 try:
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
767 uris_data = await host.bridge.URIFind(path, [key])
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
768 except Exception as e:
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
769 host.disp(f"can't find {key} URI: {e}", error=True)
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
770 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
771
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
772 try:
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
773 uri_data = uris_data[key]
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
774 except KeyError:
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
775 host.disp(
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
776 _(f"No {key} URI specified for this project, please specify service and "
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
777 f"node"),
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
778 error=True,
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
779 )
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
780 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
781
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
782 uri = uri_data["uri"]
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
783
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
784 # set extra metadata if they are specified
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
785 for data_key in ['labels']:
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
786 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
787 if uri_data is not None:
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
788 if meta_map is None:
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
789 dest = data_key
2558
501b0f827f63 jp (merge-request,common): fixed URIFinder when metadata are not needed:
Goffi <goffi@goffi.org>
parents: 2554
diff changeset
790 else:
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
791 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
792 if dest is None:
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
793 continue
2558
501b0f827f63 jp (merge-request,common): fixed URIFinder when metadata are not needed:
Goffi <goffi@goffi.org>
parents: 2554
diff changeset
794
501b0f827f63 jp (merge-request,common): fixed URIFinder when metadata are not needed:
Goffi <goffi@goffi.org>
parents: 2554
diff changeset
795 try:
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
796 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
797 except AttributeError:
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
798 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
799 else:
501b0f827f63 jp (merge-request,common): fixed URIFinder when metadata are not needed:
Goffi <goffi@goffi.org>
parents: 2554
diff changeset
800 if values is None:
501b0f827f63 jp (merge-request,common): fixed URIFinder when metadata are not needed:
Goffi <goffi@goffi.org>
parents: 2554
diff changeset
801 values = []
501b0f827f63 jp (merge-request,common): fixed URIFinder when metadata are not needed:
Goffi <goffi@goffi.org>
parents: 2554
diff changeset
802 values.extend(json.loads(new_values_json))
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
803 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
804
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
805 parsed_uri = xmpp_uri.parseXMPPUri(uri)
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
806 try:
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
807 args.service = parsed_uri["path"]
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
808 args.node = parsed_uri["node"]
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
809 except KeyError:
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
810 host.disp(_(f"Invalid URI found: {uri}"), error=True)
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3037
diff changeset
811 host.quit(C.EXIT_DATA_ERROR)