moat-kv 0.71.0__py3-none-any.whl → 0.71.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- moat/kv/__init__.py +6 -7
- moat/kv/_cfg.yaml +3 -2
- moat/kv/actor/__init__.py +2 -1
- moat/kv/actor/deletor.py +4 -1
- moat/kv/auth/__init__.py +12 -13
- moat/kv/auth/_test.py +4 -1
- moat/kv/auth/password.py +11 -7
- moat/kv/backend/mqtt.py +4 -5
- moat/kv/client.py +20 -39
- moat/kv/code.py +3 -3
- moat/kv/command/data.py +4 -3
- moat/kv/command/dump/__init__.py +36 -34
- moat/kv/command/internal.py +2 -3
- moat/kv/command/job.py +1 -2
- moat/kv/command/type.py +3 -6
- moat/kv/data.py +9 -8
- moat/kv/errors.py +16 -8
- moat/kv/mock/__init__.py +2 -12
- moat/kv/model.py +29 -33
- moat/kv/obj/__init__.py +3 -3
- moat/kv/obj/command.py +3 -3
- moat/kv/runner.py +4 -5
- moat/kv/server.py +106 -126
- moat/kv/types.py +10 -12
- {moat_kv-0.71.0.dist-info → moat_kv-0.71.7.dist-info}/METADATA +6 -2
- moat_kv-0.71.7.dist-info/RECORD +47 -0
- {moat_kv-0.71.0.dist-info → moat_kv-0.71.7.dist-info}/WHEEL +1 -1
- moat_kv-0.71.7.dist-info/licenses/LICENSE +3 -0
- moat_kv-0.71.7.dist-info/licenses/LICENSE.APACHE2 +202 -0
- moat_kv-0.71.7.dist-info/licenses/LICENSE.MIT +20 -0
- moat_kv-0.71.7.dist-info/top_level.txt +1 -0
- build/lib/docs/source/conf.py +0 -201
- build/lib/examples/pathify.py +0 -45
- build/lib/moat/kv/__init__.py +0 -19
- build/lib/moat/kv/_cfg.yaml +0 -93
- build/lib/moat/kv/_main.py +0 -91
- build/lib/moat/kv/actor/__init__.py +0 -98
- build/lib/moat/kv/actor/deletor.py +0 -139
- build/lib/moat/kv/auth/__init__.py +0 -444
- build/lib/moat/kv/auth/_test.py +0 -166
- build/lib/moat/kv/auth/password.py +0 -234
- build/lib/moat/kv/auth/root.py +0 -58
- build/lib/moat/kv/backend/__init__.py +0 -67
- build/lib/moat/kv/backend/mqtt.py +0 -71
- build/lib/moat/kv/client.py +0 -1025
- build/lib/moat/kv/code.py +0 -236
- build/lib/moat/kv/codec.py +0 -11
- build/lib/moat/kv/command/__init__.py +0 -1
- build/lib/moat/kv/command/acl.py +0 -180
- build/lib/moat/kv/command/auth.py +0 -261
- build/lib/moat/kv/command/code.py +0 -293
- build/lib/moat/kv/command/codec.py +0 -186
- build/lib/moat/kv/command/data.py +0 -265
- build/lib/moat/kv/command/dump/__init__.py +0 -143
- build/lib/moat/kv/command/error.py +0 -149
- build/lib/moat/kv/command/internal.py +0 -248
- build/lib/moat/kv/command/job.py +0 -433
- build/lib/moat/kv/command/log.py +0 -53
- build/lib/moat/kv/command/server.py +0 -114
- build/lib/moat/kv/command/type.py +0 -201
- build/lib/moat/kv/config.py +0 -46
- build/lib/moat/kv/data.py +0 -216
- build/lib/moat/kv/errors.py +0 -561
- build/lib/moat/kv/exceptions.py +0 -126
- build/lib/moat/kv/mock/__init__.py +0 -101
- build/lib/moat/kv/mock/mqtt.py +0 -159
- build/lib/moat/kv/mock/tracer.py +0 -63
- build/lib/moat/kv/model.py +0 -1069
- build/lib/moat/kv/obj/__init__.py +0 -646
- build/lib/moat/kv/obj/command.py +0 -241
- build/lib/moat/kv/runner.py +0 -1347
- build/lib/moat/kv/server.py +0 -2809
- build/lib/moat/kv/types.py +0 -513
- ci/rtd-requirements.txt +0 -4
- ci/test-requirements.txt +0 -7
- ci/travis.sh +0 -96
- debian/.gitignore +0 -7
- debian/changelog +0 -1435
- debian/control +0 -43
- debian/moat-kv/usr/lib/python3/dist-packages/docs/source/conf.py +0 -201
- debian/moat-kv/usr/lib/python3/dist-packages/examples/pathify.py +0 -45
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/__init__.py +0 -19
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/_cfg.yaml +0 -93
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/_main.py +0 -91
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/actor/__init__.py +0 -98
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/actor/deletor.py +0 -139
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/auth/__init__.py +0 -444
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/auth/_test.py +0 -166
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/auth/password.py +0 -234
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/auth/root.py +0 -58
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/backend/__init__.py +0 -67
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/backend/mqtt.py +0 -71
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/client.py +0 -1025
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/code.py +0 -236
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/codec.py +0 -11
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/__init__.py +0 -1
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/acl.py +0 -180
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/auth.py +0 -261
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/code.py +0 -293
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/codec.py +0 -186
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/data.py +0 -265
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/dump/__init__.py +0 -143
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/error.py +0 -149
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/internal.py +0 -248
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/job.py +0 -433
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/log.py +0 -53
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/server.py +0 -114
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/type.py +0 -201
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/config.py +0 -46
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/data.py +0 -216
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/errors.py +0 -561
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/exceptions.py +0 -126
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/mock/__init__.py +0 -101
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/mock/mqtt.py +0 -159
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/mock/tracer.py +0 -63
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/model.py +0 -1069
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/obj/__init__.py +0 -646
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/obj/command.py +0 -241
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/runner.py +0 -1347
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/server.py +0 -2809
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/types.py +0 -513
- debian/moat-kv.postinst +0 -3
- debian/rules +0 -20
- debian/source/format +0 -1
- debian/watch +0 -4
- docs/Makefile +0 -20
- docs/make.bat +0 -36
- docs/source/TODO.rst +0 -61
- docs/source/_static/.gitkeep +0 -0
- docs/source/acls.rst +0 -80
- docs/source/auth.rst +0 -84
- docs/source/client_protocol.rst +0 -456
- docs/source/code.rst +0 -341
- docs/source/command_line.rst +0 -1187
- docs/source/common_protocol.rst +0 -47
- docs/source/conf.py +0 -201
- docs/source/debugging.rst +0 -70
- docs/source/extend.rst +0 -37
- docs/source/history.rst +0 -36
- docs/source/index.rst +0 -75
- docs/source/model.rst +0 -54
- docs/source/overview.rst +0 -83
- docs/source/related.rst +0 -89
- docs/source/server_protocol.rst +0 -450
- docs/source/startup.rst +0 -31
- docs/source/translator.rst +0 -244
- docs/source/tutorial.rst +0 -711
- docs/source/v3.rst +0 -168
- examples/code/transform.scale.yml +0 -21
- examples/code/transform.switch.yml +0 -82
- examples/code/transform.timeslot.yml +0 -63
- examples/pathify.py +0 -45
- moat/kv/codec.py +0 -11
- moat_kv-0.71.0.dist-info/RECORD +0 -188
- moat_kv-0.71.0.dist-info/top_level.txt +0 -9
- scripts/current +0 -15
- scripts/env +0 -8
- scripts/init +0 -39
- scripts/recover +0 -17
- scripts/rotate +0 -33
- scripts/run +0 -29
- scripts/run-all +0 -10
- scripts/run-any +0 -10
- scripts/run-single +0 -15
- scripts/success +0 -4
- systemd/moat-kv-recover.service +0 -21
- systemd/moat-kv-rotate.service +0 -20
- systemd/moat-kv-rotate.timer +0 -10
- systemd/moat-kv-run-all.service +0 -26
- systemd/moat-kv-run-all@.service +0 -25
- systemd/moat-kv-run-any.service +0 -26
- systemd/moat-kv-run-any@.service +0 -25
- systemd/moat-kv-run-single.service +0 -26
- systemd/moat-kv-run-single@.service +0 -25
- systemd/moat-kv.service +0 -27
- systemd/postinst +0 -7
- systemd/sysusers +0 -3
- {moat_kv-0.71.0.dist-info → moat_kv-0.71.7.dist-info}/licenses/LICENSE.txt +0 -0
@@ -1,293 +0,0 @@
|
|
1
|
-
# command line interface
|
2
|
-
from __future__ import annotations
|
3
|
-
|
4
|
-
import sys
|
5
|
-
|
6
|
-
import asyncclick as click
|
7
|
-
from moat.util import (
|
8
|
-
NotGiven,
|
9
|
-
P,
|
10
|
-
Path,
|
11
|
-
PathLongener,
|
12
|
-
attr_args,
|
13
|
-
process_args,
|
14
|
-
yload,
|
15
|
-
yprint,
|
16
|
-
)
|
17
|
-
|
18
|
-
|
19
|
-
@click.group(invoke_without_command=True) # pylint: disable=undefined-variable
|
20
|
-
@click.argument("path", nargs=1, type=P)
|
21
|
-
@click.pass_context
|
22
|
-
async def cli(ctx, path):
|
23
|
-
"""Manage code stored in MoaT-KV."""
|
24
|
-
obj = ctx.obj
|
25
|
-
obj.path = obj.cfg["kv"]["codes"]["prefix"] + path
|
26
|
-
obj.codepath = path
|
27
|
-
|
28
|
-
if ctx.invoked_subcommand is None:
|
29
|
-
pl = PathLongener(path)
|
30
|
-
async for res in obj.client.get_tree(obj.path, long_path=False):
|
31
|
-
pl(res)
|
32
|
-
print(Path(*res.path), res.value.info, file=obj.stdout)
|
33
|
-
|
34
|
-
|
35
|
-
@cli.command()
|
36
|
-
@click.option("-s", "--script", type=click.File(mode="w", lazy=True), help="Save the code here")
|
37
|
-
@click.pass_obj
|
38
|
-
async def get(obj, script):
|
39
|
-
"""Read a code entry"""
|
40
|
-
if not len(obj.codepath):
|
41
|
-
raise click.UsageError("You need a non-empty path.")
|
42
|
-
|
43
|
-
res = await obj.client._request(action="get_value", path=obj.path, iter=False, nchain=obj.meta)
|
44
|
-
if "value" not in res:
|
45
|
-
if obj.debug:
|
46
|
-
print("No entry here.", file=sys.stderr)
|
47
|
-
sys.exit(1)
|
48
|
-
if not obj.meta:
|
49
|
-
res = res.value
|
50
|
-
if script:
|
51
|
-
code = res.pop("code", None)
|
52
|
-
if code is not None:
|
53
|
-
print(code, file=script)
|
54
|
-
yprint(res, stream=obj.stdout)
|
55
|
-
|
56
|
-
|
57
|
-
@cli.command("set")
|
58
|
-
@click.option(
|
59
|
-
"-a/-A",
|
60
|
-
"--async/--sync",
|
61
|
-
"async_",
|
62
|
-
is_flag=True,
|
63
|
-
help="The code is async / sync (default: async)",
|
64
|
-
default=True,
|
65
|
-
)
|
66
|
-
@click.option("-t", "--thread", is_flag=True, help="The code should run in a worker thread")
|
67
|
-
@click.option("-s", "--script", type=click.File(mode="r"), help="File with the code")
|
68
|
-
@click.option("-i", "--info", type=str, help="one-liner info about the code")
|
69
|
-
@click.option("-d", "--data", type=click.File(mode="r"), help="load the metadata (YAML)")
|
70
|
-
@attr_args
|
71
|
-
@click.pass_obj
|
72
|
-
async def set_(obj, thread, script, data, async_, info, **kw):
|
73
|
-
"""Save Python code.
|
74
|
-
|
75
|
-
The code may have inputs. You specify the inputs and their default
|
76
|
-
values with '-v VAR VALUE' (string), '-p VAR PATH' (MoaT-KV path), or
|
77
|
-
'-e VAR EXPR' (simple Python expression). Use '-e VAR -' to state that
|
78
|
-
VAR shall not have a default value, and '-e VAR /' to delete VAR from
|
79
|
-
the list of inputs entirely.
|
80
|
-
"""
|
81
|
-
if thread:
|
82
|
-
async_ = False
|
83
|
-
elif not async_:
|
84
|
-
async_ = None
|
85
|
-
|
86
|
-
if not len(obj.codepath):
|
87
|
-
raise click.UsageError("You need a non-empty path.")
|
88
|
-
path = obj.path
|
89
|
-
|
90
|
-
if data:
|
91
|
-
msg = yload(data)
|
92
|
-
else:
|
93
|
-
msg = await obj.client.get(path, nchain=3)
|
94
|
-
chain = NotGiven
|
95
|
-
if "value" in msg:
|
96
|
-
chain = msg.get("chain", NotGiven)
|
97
|
-
msg = msg["value"]
|
98
|
-
if async_ is not None or "is_async" not in msg:
|
99
|
-
msg["is_async"] = async_
|
100
|
-
|
101
|
-
if info is not None:
|
102
|
-
msg["info"] = info
|
103
|
-
|
104
|
-
if script:
|
105
|
-
msg["code"] = script.read()
|
106
|
-
elif "code" not in msg:
|
107
|
-
raise click.UsageError("Missing script")
|
108
|
-
|
109
|
-
if "vars" in msg:
|
110
|
-
vs = set(msg["vars"])
|
111
|
-
else:
|
112
|
-
vs = set()
|
113
|
-
vd = msg.setdefault("default", {})
|
114
|
-
|
115
|
-
vd = process_args(vd, vs=vs, **kw)
|
116
|
-
msg["vars"] = list(vs)
|
117
|
-
msg["default"] = vd
|
118
|
-
|
119
|
-
kv = {}
|
120
|
-
if chain is not NotGiven:
|
121
|
-
kv["chain"] = chain
|
122
|
-
|
123
|
-
res = await obj.client.set(obj.path, value=msg, nchain=obj.meta, **kv)
|
124
|
-
if obj.meta:
|
125
|
-
yprint(res, stream=obj.stdout)
|
126
|
-
|
127
|
-
|
128
|
-
# disabled for now
|
129
|
-
@cli.group("module", hidden=True)
|
130
|
-
async def mod():
|
131
|
-
"""
|
132
|
-
Change the code of a module stored in MoaT-KV
|
133
|
-
"""
|
134
|
-
|
135
|
-
|
136
|
-
@mod.command("get")
|
137
|
-
@click.option("-s", "--script", type=click.File(mode="w", lazy=True), help="Save the code here")
|
138
|
-
@click.argument("path", nargs=1)
|
139
|
-
@click.pass_obj # pylint: disable=function-redefined
|
140
|
-
async def get_mod(obj, path, script):
|
141
|
-
"""Read a module entry"""
|
142
|
-
path = P(path)
|
143
|
-
if not len(path):
|
144
|
-
raise click.UsageError("You need a non-empty path.")
|
145
|
-
res = await obj.client._request(
|
146
|
-
action="get_value",
|
147
|
-
path=obj.cfg["kv"]["modules"]["prefix"] + path,
|
148
|
-
iter=False,
|
149
|
-
nchain=obj.meta,
|
150
|
-
)
|
151
|
-
if not obj.meta:
|
152
|
-
res = res.value
|
153
|
-
|
154
|
-
code = res.pop("code", None)
|
155
|
-
if code is not None:
|
156
|
-
code = code.rstrip("\n \t") + "\n"
|
157
|
-
if script:
|
158
|
-
print(code, file=script)
|
159
|
-
else:
|
160
|
-
res["code"] = code
|
161
|
-
|
162
|
-
yprint(res, stream=obj.stdout)
|
163
|
-
|
164
|
-
|
165
|
-
@mod.command("set")
|
166
|
-
@click.option("-s", "--script", type=click.File(mode="r"), help="File with the module's code")
|
167
|
-
@click.option("-d", "--data", type=click.File(mode="r"), help="load the metadata (YAML)")
|
168
|
-
@click.argument("path", nargs=1) # pylint: disable=function-redefined
|
169
|
-
@click.pass_obj
|
170
|
-
async def set_mod(obj, path, script, data):
|
171
|
-
"""Save a Python module to MoaT-KV."""
|
172
|
-
path = P(path)
|
173
|
-
if not len(path):
|
174
|
-
raise click.UsageError("You need a non-empty path.")
|
175
|
-
|
176
|
-
if data:
|
177
|
-
msg = yload(data)
|
178
|
-
else:
|
179
|
-
msg = {}
|
180
|
-
chain = None
|
181
|
-
if "value" in msg:
|
182
|
-
chain = msg.get("chain", None)
|
183
|
-
msg = msg["value"]
|
184
|
-
|
185
|
-
if "code" not in msg:
|
186
|
-
if script:
|
187
|
-
raise click.UsageError("Duplicate script")
|
188
|
-
else:
|
189
|
-
if not script:
|
190
|
-
raise click.UsageError("Missing script")
|
191
|
-
msg["code"] = script.read()
|
192
|
-
|
193
|
-
res = await obj.client.set(
|
194
|
-
*obj.cfg["kv"]["modules"]["prefix"],
|
195
|
-
*path,
|
196
|
-
value=msg,
|
197
|
-
iter=False,
|
198
|
-
nchain=obj.meta,
|
199
|
-
chain=chain,
|
200
|
-
)
|
201
|
-
if obj.meta:
|
202
|
-
yprint(res, stream=obj.stdout)
|
203
|
-
|
204
|
-
|
205
|
-
@cli.command("list")
|
206
|
-
@click.option(
|
207
|
-
"-d",
|
208
|
-
"--as-dict",
|
209
|
-
default=None,
|
210
|
-
help="Structure as dictionary. The argument is the key to use "
|
211
|
-
"for values. Default: return as list",
|
212
|
-
)
|
213
|
-
@click.option(
|
214
|
-
"-m",
|
215
|
-
"--maxdepth",
|
216
|
-
type=int,
|
217
|
-
default=None,
|
218
|
-
help="Limit recursion depth. Default: whole tree",
|
219
|
-
)
|
220
|
-
@click.option(
|
221
|
-
"-M",
|
222
|
-
"--mindepth",
|
223
|
-
type=int,
|
224
|
-
default=None,
|
225
|
-
help="Starting depth. Default: whole tree",
|
226
|
-
)
|
227
|
-
@click.option("-f", "--full", is_flag=True, help="print complete entries.")
|
228
|
-
@click.option("-s", "--short", is_flag=True, help="print shortened entries.")
|
229
|
-
@click.pass_obj
|
230
|
-
async def list_(obj, as_dict, maxdepth, mindepth, full, short):
|
231
|
-
"""
|
232
|
-
List code entries.
|
233
|
-
|
234
|
-
Be aware that the whole subtree will be read before anything is
|
235
|
-
printed if you use the `--as-dict` option.
|
236
|
-
"""
|
237
|
-
|
238
|
-
if (full or as_dict) and short:
|
239
|
-
raise click.UsageError("'-f'/'-d' and '-s' are incompatible.")
|
240
|
-
kw = {}
|
241
|
-
if maxdepth is not None:
|
242
|
-
kw["max_depth"] = maxdepth
|
243
|
-
if mindepth is not None:
|
244
|
-
kw["min_depth"] = mindepth
|
245
|
-
y = {}
|
246
|
-
async for r in obj.client.get_tree(obj.path, nchain=obj.meta, **kw):
|
247
|
-
r.pop("seq", None)
|
248
|
-
path = r.pop("path")
|
249
|
-
if not full:
|
250
|
-
if "info" not in r.value:
|
251
|
-
r.value.info = f"<{len(r.value.code.splitlines())} lines>"
|
252
|
-
del r.value["code"]
|
253
|
-
|
254
|
-
if short:
|
255
|
-
print(path, "::", r.value.info)
|
256
|
-
continue
|
257
|
-
|
258
|
-
if as_dict is not None:
|
259
|
-
yy = y
|
260
|
-
for p in path:
|
261
|
-
yy = yy.setdefault(p, {})
|
262
|
-
try:
|
263
|
-
yy[as_dict] = r if obj.meta else r.value
|
264
|
-
except AttributeError:
|
265
|
-
continue
|
266
|
-
else:
|
267
|
-
y = {}
|
268
|
-
try:
|
269
|
-
y[path] = r if obj.meta else r.value
|
270
|
-
except AttributeError:
|
271
|
-
continue
|
272
|
-
yprint([y], stream=obj.stdout)
|
273
|
-
|
274
|
-
if as_dict is not None:
|
275
|
-
yprint(y, stream=obj.stdout)
|
276
|
-
return
|
277
|
-
|
278
|
-
|
279
|
-
@cli.command()
|
280
|
-
@click.pass_obj
|
281
|
-
async def delete(obj):
|
282
|
-
"""Remove a code entry"""
|
283
|
-
res = await obj.client.get(obj.path, nchain=3)
|
284
|
-
if "value" not in res:
|
285
|
-
res.info = "Does not exist."
|
286
|
-
else:
|
287
|
-
res = await obj.client.delete(obj.path, chain=res.chain)
|
288
|
-
res.info = "Deleted."
|
289
|
-
|
290
|
-
if obj.meta:
|
291
|
-
yprint(res, stream=obj.stdout)
|
292
|
-
elif obj.debug:
|
293
|
-
print(res.info, file=obj.stdout)
|
@@ -1,186 +0,0 @@
|
|
1
|
-
# command line interface
|
2
|
-
from __future__ import annotations
|
3
|
-
|
4
|
-
import asyncclick as click
|
5
|
-
from moat.util import NotGiven, P, Path, PathLongener, yload, yprint
|
6
|
-
|
7
|
-
|
8
|
-
@click.group() # pylint: disable=undefined-variable
|
9
|
-
async def cli():
|
10
|
-
"""Manage codecs and converters. Usage: … codec …"""
|
11
|
-
pass
|
12
|
-
|
13
|
-
|
14
|
-
@cli.command()
|
15
|
-
@click.option("-e", "--encode", type=click.File(mode="w", lazy=True), help="Save the encoder here")
|
16
|
-
@click.option("-d", "--decode", type=click.File(mode="w", lazy=True), help="Save the decoder here")
|
17
|
-
@click.option("-s", "--script", type=click.File(mode="w", lazy=True), help="Save the data here")
|
18
|
-
@click.argument("path", nargs=1)
|
19
|
-
@click.pass_obj
|
20
|
-
async def get(obj, path, script, encode, decode):
|
21
|
-
"""Read type information"""
|
22
|
-
path = P(path)
|
23
|
-
if not len(path):
|
24
|
-
raise click.UsageError("You need a non-empty path.")
|
25
|
-
res = await obj.client._request(
|
26
|
-
action="get_internal",
|
27
|
-
path=Path("codec") + path,
|
28
|
-
iter=False,
|
29
|
-
nchain=obj.meta,
|
30
|
-
)
|
31
|
-
if encode and res.get("encode", None) is not None:
|
32
|
-
encode.write(res.pop("encode"))
|
33
|
-
if decode and res.get("decode", None) is not None:
|
34
|
-
decode.write(res.pop("decode"))
|
35
|
-
|
36
|
-
if not obj.meta:
|
37
|
-
res = res.value
|
38
|
-
yprint(res, stream=script or obj.stdout)
|
39
|
-
|
40
|
-
|
41
|
-
@cli.command(name="list")
|
42
|
-
@click.pass_obj
|
43
|
-
@click.argument("path", nargs=1)
|
44
|
-
async def list_(obj, path):
|
45
|
-
"""List type information entries"""
|
46
|
-
res = await obj.client._request(
|
47
|
-
action="get_tree_internal",
|
48
|
-
path=Path("codec") + P(path),
|
49
|
-
iter=True,
|
50
|
-
nchain=obj.meta,
|
51
|
-
)
|
52
|
-
pl = PathLongener(())
|
53
|
-
async for r in res:
|
54
|
-
pl(r)
|
55
|
-
print(" ".join(str(x) for x in r.path), file=obj.stdout)
|
56
|
-
|
57
|
-
|
58
|
-
@cli.command("set")
|
59
|
-
@click.option("-e", "--encode", type=click.File(mode="r"), help="File with the encoder")
|
60
|
-
@click.option("-d", "--decode", type=click.File(mode="r"), help="File with the decoder")
|
61
|
-
@click.option("-D", "--data", type=click.File(mode="r"), help="File with the rest")
|
62
|
-
@click.option("-i", "--in", "in_", nargs=2, multiple=True, help="Decoding sample")
|
63
|
-
@click.option("-o", "--out", nargs=2, multiple=True, help="Encoding sample")
|
64
|
-
@click.argument("path", nargs=1)
|
65
|
-
@click.pass_obj
|
66
|
-
async def set_(obj, path, encode, decode, data, in_, out):
|
67
|
-
"""Save codec information"""
|
68
|
-
path = P(path)
|
69
|
-
if not len(path):
|
70
|
-
raise click.UsageError("You need a non-empty path.")
|
71
|
-
|
72
|
-
if data:
|
73
|
-
msg = yload(data)
|
74
|
-
else:
|
75
|
-
msg = {}
|
76
|
-
chain = NotGiven
|
77
|
-
if "value" in msg:
|
78
|
-
chain = msg.get("chain", NotGiven)
|
79
|
-
msg = msg["value"]
|
80
|
-
|
81
|
-
if "encode" in msg:
|
82
|
-
if encode:
|
83
|
-
raise click.UsageError("Duplicate encode script")
|
84
|
-
else:
|
85
|
-
if not encode:
|
86
|
-
raise click.UsageError("Missing encode script")
|
87
|
-
msg["encode"] = encode.read()
|
88
|
-
if "decode" in msg:
|
89
|
-
if decode:
|
90
|
-
raise click.UsageError("Duplicate decode script")
|
91
|
-
else:
|
92
|
-
if not decode:
|
93
|
-
raise click.UsageError("Missing decode script")
|
94
|
-
msg["decode"] = decode.read()
|
95
|
-
if in_:
|
96
|
-
msg["in"] = [(eval(a), eval(b)) for a, b in in_] # pylint: disable=eval-used
|
97
|
-
if out:
|
98
|
-
msg["out"] = [(eval(a), eval(b)) for a, b in out] # pylint: disable=eval-used
|
99
|
-
|
100
|
-
if not msg["in"]:
|
101
|
-
raise click.UsageError("Missing decode tests")
|
102
|
-
if not msg["out"]:
|
103
|
-
raise click.UsageError("Missing encode tests")
|
104
|
-
|
105
|
-
res = await obj.client._request(
|
106
|
-
action="set_internal",
|
107
|
-
value=msg,
|
108
|
-
path=Path("codec") + path,
|
109
|
-
iter=False,
|
110
|
-
nchain=obj.meta,
|
111
|
-
**({} if chain is NotGiven else {"chain": chain}),
|
112
|
-
)
|
113
|
-
if obj.meta:
|
114
|
-
yprint(res, stream=obj.stdout)
|
115
|
-
|
116
|
-
|
117
|
-
@cli.command()
|
118
|
-
@click.option("-c", "--codec", type=P, help="Codec to link to.")
|
119
|
-
@click.option("-d", "--delete", is_flag=True, help="Use to delete this converter.")
|
120
|
-
@click.option(
|
121
|
-
"-l",
|
122
|
-
"--list",
|
123
|
-
"list_",
|
124
|
-
is_flag=True,
|
125
|
-
help="Use to list this converter; '-' to list all.",
|
126
|
-
)
|
127
|
-
@click.argument("name", nargs=1)
|
128
|
-
@click.argument("path", type=P, nargs=1)
|
129
|
-
@click.pass_obj
|
130
|
-
async def convert(obj, path, codec, name, delete, list_):
|
131
|
-
"""Match a codec to a path (read, if no codec given)"""
|
132
|
-
path = P(path)
|
133
|
-
if delete and list_:
|
134
|
-
raise click.UsageError("You can't both list and delete a path.")
|
135
|
-
if not len(path) and not list_:
|
136
|
-
raise click.UsageError("You need a non-empty path.")
|
137
|
-
if codec and delete:
|
138
|
-
raise click.UsageError("You can't both set and delete a path.")
|
139
|
-
|
140
|
-
if list_:
|
141
|
-
if name == "-":
|
142
|
-
if len(path):
|
143
|
-
raise click.UsageError("You can't use a path here.")
|
144
|
-
res = await obj.client._request(
|
145
|
-
action="enum_internal",
|
146
|
-
path=Path("conv"),
|
147
|
-
iter=False,
|
148
|
-
nchain=0,
|
149
|
-
empty=True,
|
150
|
-
)
|
151
|
-
for r in res.result:
|
152
|
-
print(r, file=obj.stdout)
|
153
|
-
|
154
|
-
else:
|
155
|
-
res = await obj.client._request(
|
156
|
-
action="get_tree_internal",
|
157
|
-
path=Path("conv", name) + path,
|
158
|
-
iter=True,
|
159
|
-
nchain=obj.meta,
|
160
|
-
)
|
161
|
-
pl = PathLongener(())
|
162
|
-
async for r in res:
|
163
|
-
pl(r)
|
164
|
-
try:
|
165
|
-
print(f"{r.path} : {Path.build(r.value['codec'])}", file=obj.stdout)
|
166
|
-
except Exception as e:
|
167
|
-
print(f"{Path(r.path)} {e!r}", file=obj.stdout)
|
168
|
-
|
169
|
-
return
|
170
|
-
if delete:
|
171
|
-
res = await obj.client._request(action="delete_internal", path=Path("conv", name) + path)
|
172
|
-
else:
|
173
|
-
msg = {"codec": codec}
|
174
|
-
res = await obj.client._request(
|
175
|
-
action="set_internal",
|
176
|
-
value=msg,
|
177
|
-
path=Path("conv", name) + path,
|
178
|
-
iter=False,
|
179
|
-
nchain=obj.meta,
|
180
|
-
)
|
181
|
-
if obj.meta:
|
182
|
-
yprint(res, stream=obj.stdout)
|
183
|
-
elif type or delete:
|
184
|
-
print(res.tock, file=obj.stdout)
|
185
|
-
else:
|
186
|
-
print(" ".join(res.type), file=obj.stdout)
|