cgse-tools 2025.0.8.dev2__tar.gz → 2025.0.8.dev4__tar.gz
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.
- {cgse_tools-2025.0.8.dev2 → cgse_tools-2025.0.8.dev4}/PKG-INFO +1 -1
- {cgse_tools-2025.0.8.dev2 → cgse_tools-2025.0.8.dev4}/pyproject.toml +2 -1
- cgse_tools-2025.0.8.dev4/src/cgse_tools/cgse_commands.py +201 -0
- cgse_tools-2025.0.8.dev2/src/cgse_tools/cgse_commands.py +0 -106
- {cgse_tools-2025.0.8.dev2 → cgse_tools-2025.0.8.dev4}/.gitignore +0 -0
- {cgse_tools-2025.0.8.dev2 → cgse_tools-2025.0.8.dev4}/README.md +0 -0
- {cgse_tools-2025.0.8.dev2 → cgse_tools-2025.0.8.dev4}/src/cgse_tools/__init__.py +0 -0
- {cgse_tools-2025.0.8.dev2 → cgse_tools-2025.0.8.dev4}/src/cgse_tools/cgse_services.py +0 -0
- {cgse_tools-2025.0.8.dev2 → cgse_tools-2025.0.8.dev4}/src/egse/tools/status.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "cgse-tools"
|
|
3
|
-
version = "2025.0.8-dev.
|
|
3
|
+
version = "2025.0.8-dev.4"
|
|
4
4
|
description = "Tools for CGSE"
|
|
5
5
|
authors = [
|
|
6
6
|
{name = "IVS KU Leuven"}
|
|
@@ -36,6 +36,7 @@ cgse-tools = 'egse.tools'
|
|
|
36
36
|
# plugins for the `cgse` command, add [group] when the command has sub-commands
|
|
37
37
|
|
|
38
38
|
[project.entry-points."cgse.command.plugins"]
|
|
39
|
+
init = 'cgse_tools.cgse_commands:init'
|
|
39
40
|
top = 'cgse_tools.cgse_commands:top'
|
|
40
41
|
show = 'cgse_tools.cgse_commands:show[group]'
|
|
41
42
|
check = 'cgse_tools.cgse_commands:check[group]'
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import subprocess
|
|
3
|
+
import sys
|
|
4
|
+
import textwrap
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Annotated
|
|
7
|
+
|
|
8
|
+
import rich
|
|
9
|
+
import typer
|
|
10
|
+
|
|
11
|
+
from egse.system import format_datetime
|
|
12
|
+
|
|
13
|
+
app = typer.Typer()
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@app.command()
|
|
17
|
+
def top():
|
|
18
|
+
"""
|
|
19
|
+
A top-like interface for core services and device control servers.
|
|
20
|
+
|
|
21
|
+
Not yet implemented.
|
|
22
|
+
"""
|
|
23
|
+
print("This fancy top is not yet implemented.")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@app.command()
|
|
27
|
+
def init(project: str = ""):
|
|
28
|
+
"""Initialize your project."""
|
|
29
|
+
from rich.prompt import Prompt, Confirm
|
|
30
|
+
|
|
31
|
+
project = project.upper()
|
|
32
|
+
site_id = None
|
|
33
|
+
|
|
34
|
+
rich.print("[light_steel_blue]Please note default values are given between \[brackets].[/]")
|
|
35
|
+
|
|
36
|
+
answer = Prompt.ask(f"What is the name of the project [{project}] ?")
|
|
37
|
+
if answer:
|
|
38
|
+
project = answer.upper()
|
|
39
|
+
while not site_id:
|
|
40
|
+
answer = Prompt.ask("What is the site identifier ?")
|
|
41
|
+
if answer:
|
|
42
|
+
site_id = answer.upper()
|
|
43
|
+
else:
|
|
44
|
+
answer = Confirm.ask("Abort?")
|
|
45
|
+
if answer:
|
|
46
|
+
return
|
|
47
|
+
|
|
48
|
+
data_storage_location = f"~/data/{project}/{site_id}/"
|
|
49
|
+
answer = Prompt.ask(f"Where can the project data be stored [{data_storage_location}] ?")
|
|
50
|
+
if answer:
|
|
51
|
+
data_storage_location = answer
|
|
52
|
+
|
|
53
|
+
conf_data_location = f"~/data/{project}/{site_id}/conf/"
|
|
54
|
+
answer = Prompt.ask(f"Where will the configuration data be located [{conf_data_location}] ?")
|
|
55
|
+
if answer:
|
|
56
|
+
conf_data_location = answer
|
|
57
|
+
|
|
58
|
+
log_file_location = f"~/data/{project}/{site_id}/log/"
|
|
59
|
+
answer = Prompt.ask(f"Where will the logging messages be stored [{log_file_location}] ?")
|
|
60
|
+
if answer:
|
|
61
|
+
log_file_location = answer
|
|
62
|
+
|
|
63
|
+
local_settings_path = f"~/data/{project}/{site_id}/local_settings.yaml"
|
|
64
|
+
answer = Prompt.ask(f"Where shall I create a local settings YAML file [{local_settings_path}] ?")
|
|
65
|
+
if answer:
|
|
66
|
+
local_settings_path = answer
|
|
67
|
+
|
|
68
|
+
Path(data_storage_location).expanduser().mkdir(exist_ok=True, parents=True)
|
|
69
|
+
(Path(data_storage_location).expanduser() / "daily").mkdir(exist_ok=True, parents=True)
|
|
70
|
+
(Path(data_storage_location).expanduser() / "obs").mkdir(exist_ok=True, parents=True)
|
|
71
|
+
Path(conf_data_location).expanduser().mkdir(exist_ok=True, parents=True)
|
|
72
|
+
Path(log_file_location).expanduser().mkdir(exist_ok=True, parents=True)
|
|
73
|
+
|
|
74
|
+
with open(Path(local_settings_path).expanduser(), 'w') as fd:
|
|
75
|
+
fd.write(
|
|
76
|
+
textwrap.dedent(
|
|
77
|
+
f"""\
|
|
78
|
+
SITE:
|
|
79
|
+
ID: {site_id}
|
|
80
|
+
"""
|
|
81
|
+
)
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
answer = Confirm.ask("Shall I add the environment to your ~/bash_profile ?")
|
|
85
|
+
if answer:
|
|
86
|
+
with open(Path("~/.bash_profile").expanduser(), 'a') as fd:
|
|
87
|
+
fd.write(
|
|
88
|
+
textwrap.dedent(
|
|
89
|
+
f"""
|
|
90
|
+
# Environment for project {project} added by `cgse init` at {format_datetime()}
|
|
91
|
+
export PROJECT={project}
|
|
92
|
+
export SITE_ID={site_id}
|
|
93
|
+
export {project}_DATA_STORAGE_LOCATION={data_storage_location}
|
|
94
|
+
export {project}_CONF_DATA_LOCATION={conf_data_location}
|
|
95
|
+
export {project}_LOG_FILE_LOCATION={log_file_location}
|
|
96
|
+
export {project}_LOCAL_SETTINGS={local_settings_path}
|
|
97
|
+
"""
|
|
98
|
+
)
|
|
99
|
+
)
|
|
100
|
+
else:
|
|
101
|
+
rich.print(
|
|
102
|
+
textwrap.dedent(
|
|
103
|
+
f"""
|
|
104
|
+
# -> Add the following lines to your bash profile or equivalent
|
|
105
|
+
|
|
106
|
+
export PROJECT={project}
|
|
107
|
+
export SITE_ID={site_id}
|
|
108
|
+
export {project}_DATA_STORAGE_LOCATION={data_storage_location}
|
|
109
|
+
export {project}_CONF_DATA_LOCATION={conf_data_location}
|
|
110
|
+
export {project}_LOG_FILE_LOCATION={log_file_location}
|
|
111
|
+
export {project}_LOCAL_SETTINGS={local_settings_path}
|
|
112
|
+
"""
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
show = typer.Typer(help="Show information about settings, environment, setup, ...", no_args_is_help=True)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@show.command(name="settings")
|
|
122
|
+
def show_settings():
|
|
123
|
+
proc = subprocess.Popen(
|
|
124
|
+
[sys.executable, "-m", "egse.settings"],
|
|
125
|
+
stdout=subprocess.PIPE,
|
|
126
|
+
stderr=subprocess.PIPE
|
|
127
|
+
)
|
|
128
|
+
stdout, stderr = proc.communicate()
|
|
129
|
+
rich.print(stdout.decode(), end='')
|
|
130
|
+
if stderr:
|
|
131
|
+
rich.print(f"[red]{stderr.decode()}[/]")
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
@show.command(name="env")
|
|
135
|
+
def show_env(
|
|
136
|
+
mkdir: Annotated[bool, typer.Option(help="Create the missing folder")] = None,
|
|
137
|
+
full: Annotated[bool, typer.Option(help="Provide additional info")] = None,
|
|
138
|
+
doc: Annotated[bool, typer.Option(help="Provide documentation on environment variables")] = None,
|
|
139
|
+
):
|
|
140
|
+
options = [opt for opt, flag in [("--mkdir", mkdir), ("--full", full), ("--doc", doc)] if flag]
|
|
141
|
+
|
|
142
|
+
cmd = [sys.executable, "-m", "egse.env"]
|
|
143
|
+
cmd += options if options else []
|
|
144
|
+
|
|
145
|
+
proc = subprocess.Popen(
|
|
146
|
+
cmd,
|
|
147
|
+
stdout=subprocess.PIPE,
|
|
148
|
+
stderr=subprocess.PIPE
|
|
149
|
+
)
|
|
150
|
+
stdout, stderr = proc.communicate()
|
|
151
|
+
rich.print(stdout.decode(), end='')
|
|
152
|
+
if stderr:
|
|
153
|
+
rich.print(f"[red]{stderr.decode()}[/]")
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
check = typer.Typer(help="Check installation, settings, required files, etc.", no_args_is_help=True)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
@check.command(name="setups")
|
|
160
|
+
def check_setups():
|
|
161
|
+
"""Perform a number of checks on the SETUP files."""
|
|
162
|
+
|
|
163
|
+
# What can we check with respect to the setups?
|
|
164
|
+
#
|
|
165
|
+
# - CONF_DATA_LOCATION
|
|
166
|
+
|
|
167
|
+
from egse.env import get_conf_data_location
|
|
168
|
+
from egse.env import get_site_id
|
|
169
|
+
from egse.config import find_files
|
|
170
|
+
|
|
171
|
+
any_errors = 0
|
|
172
|
+
|
|
173
|
+
conf_data_location = get_conf_data_location()
|
|
174
|
+
site_id = get_site_id()
|
|
175
|
+
|
|
176
|
+
# ---------- check if the <PROJECT>_CONF_DATA_LOCATION is set
|
|
177
|
+
|
|
178
|
+
if not conf_data_location:
|
|
179
|
+
any_errors += 1
|
|
180
|
+
rich.print("[red]The location of the configuration data can not be determined, check your environment.[/]")
|
|
181
|
+
|
|
182
|
+
if not Path(conf_data_location).exists():
|
|
183
|
+
any_errors += 1
|
|
184
|
+
rich.print(f"[red]The location of the configuration data doesn't exist: {conf_data_location!s}[/]")
|
|
185
|
+
|
|
186
|
+
# ---------- check if there is at least one SETUP in the configuration data folder
|
|
187
|
+
|
|
188
|
+
files = list(find_files("SETUP*.yaml", root=conf_data_location))
|
|
189
|
+
|
|
190
|
+
if not files:
|
|
191
|
+
any_errors += 1
|
|
192
|
+
rich.print(f"[red]No SETUP files were found at {conf_data_location}[/]")
|
|
193
|
+
|
|
194
|
+
regex = re.compile(f"SETUP_{site_id}_00000_.*.yaml")
|
|
195
|
+
|
|
196
|
+
if not any(True for file in files if regex.search(str(file))):
|
|
197
|
+
any_errors += 1
|
|
198
|
+
rich.print(f"[red]The is no Zero SETUP for {site_id} in {conf_data_location}[/]")
|
|
199
|
+
|
|
200
|
+
if not any_errors:
|
|
201
|
+
rich.print("[green]everything seems to be ok.[/]")
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import re
|
|
2
|
-
import subprocess
|
|
3
|
-
import sys
|
|
4
|
-
from pathlib import Path
|
|
5
|
-
from typing import Annotated
|
|
6
|
-
|
|
7
|
-
import rich
|
|
8
|
-
import typer
|
|
9
|
-
|
|
10
|
-
app = typer.Typer()
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@app.command()
|
|
14
|
-
def top():
|
|
15
|
-
"""
|
|
16
|
-
A top-like interface for core services and device control servers.
|
|
17
|
-
|
|
18
|
-
Not yet implemented.
|
|
19
|
-
"""
|
|
20
|
-
print("This fancy top is not yet implemented.")
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
show = typer.Typer(help="Show information about settings, environment, setup, ...", no_args_is_help=True)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
@show.command(name="settings")
|
|
27
|
-
def show_settings():
|
|
28
|
-
proc = subprocess.Popen(
|
|
29
|
-
[sys.executable, "-m", "egse.settings"],
|
|
30
|
-
stdout=subprocess.PIPE,
|
|
31
|
-
stderr=subprocess.PIPE
|
|
32
|
-
)
|
|
33
|
-
stdout, stderr = proc.communicate()
|
|
34
|
-
rich.print(stdout.decode(), end='')
|
|
35
|
-
if stderr:
|
|
36
|
-
rich.print(f"[red]{stderr.decode()}[/]")
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
@show.command(name="env")
|
|
40
|
-
def show_env(
|
|
41
|
-
mkdir: Annotated[bool, typer.Option(help="Create the missing folder")] = None,
|
|
42
|
-
full: Annotated[bool, typer.Option(help="Provide additional info")] = None,
|
|
43
|
-
doc: Annotated[bool, typer.Option(help="Provide documentation on environment variables")] = None,
|
|
44
|
-
):
|
|
45
|
-
options = [opt for opt, flag in [("--mkdir", mkdir), ("--full", full), ("--doc", doc)] if flag]
|
|
46
|
-
|
|
47
|
-
cmd = [sys.executable, "-m", "egse.env"]
|
|
48
|
-
cmd += options if options else []
|
|
49
|
-
|
|
50
|
-
proc = subprocess.Popen(
|
|
51
|
-
cmd,
|
|
52
|
-
stdout=subprocess.PIPE,
|
|
53
|
-
stderr=subprocess.PIPE
|
|
54
|
-
)
|
|
55
|
-
stdout, stderr = proc.communicate()
|
|
56
|
-
rich.print(stdout.decode(), end='')
|
|
57
|
-
if stderr:
|
|
58
|
-
rich.print(f"[red]{stderr.decode()}[/]")
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
check = typer.Typer(help="Check installation, settings, required files, etc.", no_args_is_help=True)
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
@check.command(name="setups")
|
|
65
|
-
def check_setups():
|
|
66
|
-
"""Perform a number of checks on the SETUP files."""
|
|
67
|
-
|
|
68
|
-
# What can we check with respect to the setups?
|
|
69
|
-
#
|
|
70
|
-
# - CONF_DATA_LOCATION
|
|
71
|
-
|
|
72
|
-
from egse.env import get_conf_data_location
|
|
73
|
-
from egse.env import get_site_id
|
|
74
|
-
from egse.config import find_files
|
|
75
|
-
|
|
76
|
-
any_errors = 0
|
|
77
|
-
|
|
78
|
-
conf_data_location = get_conf_data_location()
|
|
79
|
-
site_id = get_site_id()
|
|
80
|
-
|
|
81
|
-
# ---------- check if the <PROJECT>_CONF_DATA_LOCATION is set
|
|
82
|
-
|
|
83
|
-
if not conf_data_location:
|
|
84
|
-
any_errors += 1
|
|
85
|
-
rich.print("[red]The location of the configuration data can not be determined, check your environment.[/]")
|
|
86
|
-
|
|
87
|
-
if not Path(conf_data_location).exists():
|
|
88
|
-
any_errors += 1
|
|
89
|
-
rich.print(f"[red]The location of the configuration data doesn't exist: {conf_data_location!s}[/]")
|
|
90
|
-
|
|
91
|
-
# ---------- check if there is at least one SETUP in the configuration data folder
|
|
92
|
-
|
|
93
|
-
files = list(find_files("SETUP*.yaml", root=conf_data_location))
|
|
94
|
-
|
|
95
|
-
if not files:
|
|
96
|
-
any_errors += 1
|
|
97
|
-
rich.print(f"[red]No SETUP files were found at {conf_data_location}[/]")
|
|
98
|
-
|
|
99
|
-
regex = re.compile(f"SETUP_{site_id}_00000_.*.yaml")
|
|
100
|
-
|
|
101
|
-
if not any(True for file in files if regex.search(str(file))):
|
|
102
|
-
any_errors += 1
|
|
103
|
-
rich.print(f"[red]The is no Zero SETUP for {site_id} in {conf_data_location}[/]")
|
|
104
|
-
|
|
105
|
-
if not any_errors:
|
|
106
|
-
rich.print("[green]everything seems to be ok.[/]")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|