gOdoo-cli 0.7.0__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.
- godoo_cli/__init__.py +2 -0
- godoo_cli/__main__.py +5 -0
- godoo_cli/cli.py +87 -0
- godoo_cli/cli_common.py +183 -0
- godoo_cli/commands/__init__.py +9 -0
- godoo_cli/commands/backup/__init__.py +1 -0
- godoo_cli/commands/backup/cli.py +17 -0
- godoo_cli/commands/backup/load.py +110 -0
- godoo_cli/commands/backup/pull.py +134 -0
- godoo_cli/commands/backup/util.py +35 -0
- godoo_cli/commands/bootstrap.py +187 -0
- godoo_cli/commands/config.py +43 -0
- godoo_cli/commands/db/__init__.py +1 -0
- godoo_cli/commands/db/cli.py +18 -0
- godoo_cli/commands/db/connection.py +94 -0
- godoo_cli/commands/db/passwords.py +56 -0
- godoo_cli/commands/db/query.py +41 -0
- godoo_cli/commands/launch.py +325 -0
- godoo_cli/commands/rpc/__init__.py +8 -0
- godoo_cli/commands/rpc/cli.py +34 -0
- godoo_cli/commands/rpc/config_parameters.py +48 -0
- godoo_cli/commands/rpc/importer.py +70 -0
- godoo_cli/commands/rpc/modules.py +144 -0
- godoo_cli/commands/rpc/translations.py +129 -0
- godoo_cli/commands/shell.py +45 -0
- godoo_cli/commands/source_get.py +279 -0
- godoo_cli/commands/test.py +126 -0
- godoo_cli/git/__init__.py +4 -0
- godoo_cli/git/git_odoo.py +89 -0
- godoo_cli/git/git_odoo_addons.py +95 -0
- godoo_cli/git/git_repo.py +207 -0
- godoo_cli/git/git_url.py +152 -0
- godoo_cli/git/zip_download.py +49 -0
- godoo_cli/helpers/__init__.py +1 -0
- godoo_cli/helpers/bootstrap.py +61 -0
- godoo_cli/helpers/cli.py +15 -0
- godoo_cli/helpers/odoo_files.py +278 -0
- godoo_cli/helpers/odoo_manifest.py +112 -0
- godoo_cli/helpers/system.py +176 -0
- godoo_cli/version.py +1 -0
- godoo_cli-0.7.0.dist-info/LICENSE +165 -0
- godoo_cli-0.7.0.dist-info/METADATA +197 -0
- godoo_cli-0.7.0.dist-info/RECORD +45 -0
- godoo_cli-0.7.0.dist-info/WHEEL +4 -0
- godoo_cli-0.7.0.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import re
|
|
3
|
+
import threading
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import List
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
|
|
9
|
+
from ..cli_common import CommonCLI
|
|
10
|
+
from ..helpers.odoo_files import get_odoo_module_paths, odoo_bin_get_version
|
|
11
|
+
from ..helpers.system import run_cmd
|
|
12
|
+
from .bootstrap import bootstrap_odoo
|
|
13
|
+
from .rpc import import_to_odoo
|
|
14
|
+
from .source_get import update_odoo_conf
|
|
15
|
+
|
|
16
|
+
CLI = CommonCLI()
|
|
17
|
+
|
|
18
|
+
LOGGER = logging.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _launch_command(
|
|
22
|
+
odoo_path: Path,
|
|
23
|
+
odoo_conf_path: Path,
|
|
24
|
+
extra_cmd_args: List[str],
|
|
25
|
+
workspace_addon_path: Path,
|
|
26
|
+
upgrade_workspace_modules: bool = True,
|
|
27
|
+
):
|
|
28
|
+
"""Build Odoo Launch command
|
|
29
|
+
|
|
30
|
+
Parameters
|
|
31
|
+
----------
|
|
32
|
+
odoo_path : Path
|
|
33
|
+
Path to odoo-bin folder
|
|
34
|
+
odoo_conf_path : Path
|
|
35
|
+
Path to odoo.conf
|
|
36
|
+
extra_cmd_args : List[str]
|
|
37
|
+
extra args to pass to odoo-bin
|
|
38
|
+
workspace_addon_path : Path
|
|
39
|
+
Path to dev workspace addons folder
|
|
40
|
+
upgrade_workspace_modules : bool, optional
|
|
41
|
+
upgrade workspace addons, by default True
|
|
42
|
+
"""
|
|
43
|
+
upgrade_addons = [f.name for f in get_odoo_module_paths(workspace_addon_path)] if upgrade_workspace_modules else []
|
|
44
|
+
if any(["-u" in i or "--update" in i for i in extra_cmd_args]):
|
|
45
|
+
upgrade_addons = []
|
|
46
|
+
update_addon_string = "--update " + ",".join(upgrade_addons) if upgrade_addons else ""
|
|
47
|
+
|
|
48
|
+
odoo_cmd = [
|
|
49
|
+
str(odoo_path.absolute()) + "/odoo-bin",
|
|
50
|
+
update_addon_string,
|
|
51
|
+
f"-c {str(odoo_conf_path.absolute())}",
|
|
52
|
+
] + extra_cmd_args
|
|
53
|
+
odoo_cmd = list(filter(None, odoo_cmd))
|
|
54
|
+
return " ".join(odoo_cmd)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def pre_launch(
|
|
58
|
+
odoo_main_path: Path,
|
|
59
|
+
workspace_addon_path: Path,
|
|
60
|
+
thirdparty_addon_path: Path,
|
|
61
|
+
odoo_conf_path: Path,
|
|
62
|
+
db_filter: str,
|
|
63
|
+
db_host: str,
|
|
64
|
+
db_port: int,
|
|
65
|
+
db_name: str,
|
|
66
|
+
db_user: str,
|
|
67
|
+
db_password: str,
|
|
68
|
+
odoo_demo: bool,
|
|
69
|
+
dev_mode: bool,
|
|
70
|
+
multithread_worker_count: int = 0,
|
|
71
|
+
extra_launch_args: List[str] = None,
|
|
72
|
+
extra_bootstrap_args: List[str] = None,
|
|
73
|
+
log_file_path: Path = None,
|
|
74
|
+
install_workspace_addons: bool = True,
|
|
75
|
+
install_base: bool = True,
|
|
76
|
+
launch_or_bootstrap: bool = False,
|
|
77
|
+
):
|
|
78
|
+
"""Start Bootstrap if no config file is found. And return Launch CMD.
|
|
79
|
+
|
|
80
|
+
Parameters
|
|
81
|
+
----------
|
|
82
|
+
odoo_main_path : Path
|
|
83
|
+
Path to Odoo-bin folder
|
|
84
|
+
workspace_addon_path : Path
|
|
85
|
+
Path to workspace addons
|
|
86
|
+
thirdparty_addon_path : Path
|
|
87
|
+
path to thirdparty addons folder
|
|
88
|
+
odoo_conf_path : Path
|
|
89
|
+
path to odoo conf
|
|
90
|
+
db_filter : str
|
|
91
|
+
odoo.conf db_filter
|
|
92
|
+
db_host : str
|
|
93
|
+
database host url. Empty string for Unix sock
|
|
94
|
+
db_port : int
|
|
95
|
+
database port. 0 for unix sock
|
|
96
|
+
db_name : str
|
|
97
|
+
odoo main database name
|
|
98
|
+
db_user : str
|
|
99
|
+
database user
|
|
100
|
+
db_password : str
|
|
101
|
+
database password
|
|
102
|
+
odoo_demo : bool
|
|
103
|
+
if false, add --without-demo to bootstrap
|
|
104
|
+
dev_mode : bool
|
|
105
|
+
add --dev... to cmd
|
|
106
|
+
install_base : bool
|
|
107
|
+
install web, and base
|
|
108
|
+
install_workspace_addons : bool
|
|
109
|
+
install all modules in workspace folder
|
|
110
|
+
extra_args : List[str]
|
|
111
|
+
extra launch CMD args
|
|
112
|
+
extra_bootstrap_args : List[str]
|
|
113
|
+
extra bootstrap cmd args
|
|
114
|
+
log_file_path : Path
|
|
115
|
+
path to odoo.log (stdout log if empty)
|
|
116
|
+
multithread_worker_count : int
|
|
117
|
+
count of multithread workser
|
|
118
|
+
launch_or_bootstrap: bool, optional
|
|
119
|
+
Only return launch cmd if bootstrap did not run
|
|
120
|
+
|
|
121
|
+
Returns
|
|
122
|
+
-------
|
|
123
|
+
Union[int,str]
|
|
124
|
+
Int return code of bootstrap if not 0 else launch cmd as string
|
|
125
|
+
"""
|
|
126
|
+
LOGGER.info("Starting godoo Init Script")
|
|
127
|
+
|
|
128
|
+
extra_odoo_args = []
|
|
129
|
+
if log_file_path is not None:
|
|
130
|
+
log_file_path.unlink(missing_ok=True)
|
|
131
|
+
extra_odoo_args.append("--logfile " + str(log_file_path.absolute()))
|
|
132
|
+
|
|
133
|
+
bootstraped = odoo_conf_path.exists()
|
|
134
|
+
LOGGER.info("Bootstrap Flag Status: %s", bootstraped)
|
|
135
|
+
ret = ""
|
|
136
|
+
if not bootstraped:
|
|
137
|
+
_extra_bootstrap_args = extra_odoo_args.copy()
|
|
138
|
+
if ea := extra_bootstrap_args:
|
|
139
|
+
_extra_bootstrap_args += ea
|
|
140
|
+
if not odoo_demo:
|
|
141
|
+
_extra_bootstrap_args += ["--without-demo all"]
|
|
142
|
+
if not install_base:
|
|
143
|
+
install_workspace_addons = False
|
|
144
|
+
ret = bootstrap_odoo(
|
|
145
|
+
db_name=db_name,
|
|
146
|
+
db_filter=db_filter,
|
|
147
|
+
db_user=db_user,
|
|
148
|
+
db_password=db_password,
|
|
149
|
+
db_host=db_host,
|
|
150
|
+
db_port=db_port,
|
|
151
|
+
thirdparty_addon_path=thirdparty_addon_path,
|
|
152
|
+
odoo_main_path=odoo_main_path,
|
|
153
|
+
odoo_conf_path=odoo_conf_path,
|
|
154
|
+
extra_cmd_args=_extra_bootstrap_args,
|
|
155
|
+
no_install_base=not install_base,
|
|
156
|
+
no_install_workspace_modules=not install_workspace_addons,
|
|
157
|
+
multithread_worker_count=multithread_worker_count,
|
|
158
|
+
)
|
|
159
|
+
bootstraped = ret == 0
|
|
160
|
+
if not bootstraped:
|
|
161
|
+
return ret
|
|
162
|
+
if install_workspace_addons and bootstraped:
|
|
163
|
+
install_workspace_addons = False
|
|
164
|
+
|
|
165
|
+
if launch_or_bootstrap:
|
|
166
|
+
return
|
|
167
|
+
|
|
168
|
+
if ea := extra_launch_args:
|
|
169
|
+
extra_odoo_args += ea
|
|
170
|
+
|
|
171
|
+
odoo_main_path = odoo_main_path
|
|
172
|
+
odoo_version = odoo_bin_get_version(odoo_main_path)
|
|
173
|
+
|
|
174
|
+
update_odoo_conf(
|
|
175
|
+
odoo_conf_path=odoo_conf_path,
|
|
176
|
+
odoo_main_path=odoo_main_path,
|
|
177
|
+
workspace_addon_path=workspace_addon_path,
|
|
178
|
+
thirdparty_addon_path=thirdparty_addon_path,
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
if dev_mode:
|
|
182
|
+
extra_odoo_args.append("--dev xml,qweb,reload")
|
|
183
|
+
if "16.0" in odoo_version:
|
|
184
|
+
extra_odoo_args[-1] += ",werkzeug"
|
|
185
|
+
|
|
186
|
+
if multithread_worker_count == 0:
|
|
187
|
+
extra_odoo_args.append("--workers 0")
|
|
188
|
+
|
|
189
|
+
return _launch_command(
|
|
190
|
+
odoo_path=odoo_main_path,
|
|
191
|
+
odoo_conf_path=odoo_conf_path,
|
|
192
|
+
extra_cmd_args=extra_odoo_args,
|
|
193
|
+
workspace_addon_path=workspace_addon_path,
|
|
194
|
+
upgrade_workspace_modules=install_workspace_addons,
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
@CLI.unpacker
|
|
199
|
+
@CLI.arg_annotator
|
|
200
|
+
def launch_odoo(
|
|
201
|
+
odoo_main_path=CLI.odoo_paths.bin_path,
|
|
202
|
+
workspace_addon_path=CLI.odoo_paths.workspace_addon_path,
|
|
203
|
+
thirdparty_addon_path=CLI.odoo_paths.thirdparty_addon_path,
|
|
204
|
+
odoo_conf_path=CLI.odoo_paths.conf_path,
|
|
205
|
+
db_filter=CLI.database.db_filter,
|
|
206
|
+
db_host=CLI.database.db_host,
|
|
207
|
+
db_port=CLI.database.db_port,
|
|
208
|
+
db_name=CLI.database.db_name,
|
|
209
|
+
db_user=CLI.database.db_user,
|
|
210
|
+
db_password=CLI.database.db_password,
|
|
211
|
+
odoo_demo=CLI.odoo_launch.odoo_demo,
|
|
212
|
+
dev_mode=CLI.odoo_launch.dev_mode,
|
|
213
|
+
no_install_base=CLI.odoo_launch.no_install_base,
|
|
214
|
+
no_install_workspace_modules=CLI.odoo_launch.no_install_workspace_modules,
|
|
215
|
+
extra_args=CLI.odoo_launch.extra_cmd_args,
|
|
216
|
+
extra_bootstrap_args=CLI.odoo_launch.extra_cmd_args,
|
|
217
|
+
log_file_path=CLI.odoo_launch.log_file_path,
|
|
218
|
+
multithread_worker_count=CLI.odoo_launch.multithread_worker_count,
|
|
219
|
+
):
|
|
220
|
+
"""
|
|
221
|
+
Launch Odoo, Bootstrap if bootstrapflag is not present.
|
|
222
|
+
"""
|
|
223
|
+
|
|
224
|
+
launch_cmd = pre_launch(
|
|
225
|
+
odoo_main_path=odoo_main_path,
|
|
226
|
+
workspace_addon_path=workspace_addon_path,
|
|
227
|
+
thirdparty_addon_path=thirdparty_addon_path,
|
|
228
|
+
odoo_conf_path=odoo_conf_path,
|
|
229
|
+
db_filter=db_filter,
|
|
230
|
+
db_host=db_host,
|
|
231
|
+
db_port=db_port,
|
|
232
|
+
db_name=db_name,
|
|
233
|
+
db_user=db_user,
|
|
234
|
+
db_password=db_password,
|
|
235
|
+
odoo_demo=odoo_demo,
|
|
236
|
+
dev_mode=dev_mode,
|
|
237
|
+
install_base=not no_install_base,
|
|
238
|
+
install_workspace_addons=not no_install_workspace_modules,
|
|
239
|
+
extra_launch_args=extra_args,
|
|
240
|
+
extra_bootstrap_args=extra_bootstrap_args,
|
|
241
|
+
log_file_path=log_file_path,
|
|
242
|
+
multithread_worker_count=multithread_worker_count,
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
if not isinstance(launch_cmd, str):
|
|
246
|
+
LOGGER.error("godoo Launch Failed. Bootstrap unsuccessfull. Aborting Launch...")
|
|
247
|
+
return CLI.returner(launch_cmd)
|
|
248
|
+
|
|
249
|
+
LOGGER.info("Launching Odoo")
|
|
250
|
+
return CLI.returner(run_cmd(launch_cmd).returncode)
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
@CLI.arg_annotator
|
|
254
|
+
def launch_import(
|
|
255
|
+
load_data_path: List[Path] = typer.Argument(
|
|
256
|
+
...,
|
|
257
|
+
help="Starts Async Importer Job with provided path(s).",
|
|
258
|
+
),
|
|
259
|
+
odoo_main_path=CLI.odoo_paths.bin_path,
|
|
260
|
+
workspace_addon_path=CLI.odoo_paths.workspace_addon_path,
|
|
261
|
+
thirdparty_addon_path=CLI.odoo_paths.thirdparty_addon_path,
|
|
262
|
+
odoo_conf_path=CLI.odoo_paths.conf_path,
|
|
263
|
+
db_filter=CLI.database.db_filter,
|
|
264
|
+
db_host=CLI.database.db_host,
|
|
265
|
+
db_port=CLI.database.db_port,
|
|
266
|
+
db_name=CLI.database.db_name,
|
|
267
|
+
db_user=CLI.database.db_user,
|
|
268
|
+
db_password=CLI.database.db_password,
|
|
269
|
+
rpc_host=CLI.rpc.rpc_host,
|
|
270
|
+
rpc_user=CLI.rpc.rpc_user,
|
|
271
|
+
rpc_password=CLI.rpc.rpc_password,
|
|
272
|
+
odoo_demo=CLI.odoo_launch.odoo_demo,
|
|
273
|
+
dev_mode=CLI.odoo_launch.dev_mode,
|
|
274
|
+
no_install_base=CLI.odoo_launch.no_install_base,
|
|
275
|
+
no_install_workspace_modules=CLI.odoo_launch.no_install_workspace_modules,
|
|
276
|
+
extra_launch_args=CLI.odoo_launch.extra_cmd_args,
|
|
277
|
+
extra_bootstrap_args=CLI.odoo_launch.extra_cmd_args,
|
|
278
|
+
log_file_path=CLI.odoo_launch.log_file_path,
|
|
279
|
+
multithread_worker_count=CLI.odoo_launch.multithread_worker_count,
|
|
280
|
+
):
|
|
281
|
+
"""Bootstrap and Start odoo. Launches RPC import in second thread."""
|
|
282
|
+
|
|
283
|
+
launch_cmd = pre_launch(
|
|
284
|
+
odoo_main_path=odoo_main_path,
|
|
285
|
+
workspace_addon_path=workspace_addon_path,
|
|
286
|
+
thirdparty_addon_path=thirdparty_addon_path,
|
|
287
|
+
odoo_conf_path=odoo_conf_path,
|
|
288
|
+
db_filter=db_filter,
|
|
289
|
+
db_host=db_host,
|
|
290
|
+
db_port=db_port,
|
|
291
|
+
db_name=db_name,
|
|
292
|
+
db_user=db_user,
|
|
293
|
+
db_password=db_password,
|
|
294
|
+
odoo_demo=odoo_demo,
|
|
295
|
+
dev_mode=dev_mode,
|
|
296
|
+
install_base=not no_install_base,
|
|
297
|
+
install_workspace_addons=not no_install_workspace_modules,
|
|
298
|
+
extra_launch_args=extra_launch_args,
|
|
299
|
+
extra_bootstrap_args=extra_bootstrap_args,
|
|
300
|
+
log_file_path=log_file_path,
|
|
301
|
+
multithread_worker_count=multithread_worker_count,
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
if not isinstance(launch_cmd, str):
|
|
305
|
+
LOGGER.error("godoo Launch Failed. Bootstrap unsuccessfull. Aborting Launch...")
|
|
306
|
+
return CLI.returner(launch_cmd)
|
|
307
|
+
|
|
308
|
+
launch_cmd = re.sub(r"(--dev [\w,]+)(,reload)", r"\1", launch_cmd) # Remove reload option from CMD String
|
|
309
|
+
|
|
310
|
+
LOGGER.info("Starting Data Importer Thread for: '%s'", ", ".join(map(str, load_data_path)))
|
|
311
|
+
loader_thread = threading.Thread(
|
|
312
|
+
target=import_to_odoo,
|
|
313
|
+
name="DataLoader",
|
|
314
|
+
kwargs={
|
|
315
|
+
"read_paths": load_data_path,
|
|
316
|
+
"rpc_host": rpc_host,
|
|
317
|
+
"rpc_database": db_name,
|
|
318
|
+
"rpc_user": rpc_user,
|
|
319
|
+
"rpc_password": rpc_password,
|
|
320
|
+
},
|
|
321
|
+
)
|
|
322
|
+
loader_thread.start()
|
|
323
|
+
|
|
324
|
+
LOGGER.info("Launching Odoo")
|
|
325
|
+
return CLI.returner(run_cmd(launch_cmd).returncode)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import typer
|
|
2
|
+
|
|
3
|
+
from .config_parameters import set_config_parameter
|
|
4
|
+
from .importer import import_to_odoo
|
|
5
|
+
from .modules import install_modules, uninstall_modules
|
|
6
|
+
from .translations import dump_translations
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def modules_cli_app():
|
|
10
|
+
app = typer.Typer(
|
|
11
|
+
no_args_is_help=True,
|
|
12
|
+
help="Wrapper around Odoo modules. (Install/upgrade, etc)",
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
app.command(name="install")(install_modules)
|
|
16
|
+
app.command(name="uninstall")(uninstall_modules)
|
|
17
|
+
app.command(name="dump-translation")(dump_translations)
|
|
18
|
+
return app
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def rpc_cli_app():
|
|
22
|
+
app = typer.Typer(
|
|
23
|
+
no_args_is_help=True,
|
|
24
|
+
help="Functions that act on a running Odoo instance via RPC.",
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
app.add_typer(
|
|
28
|
+
typer_instance=modules_cli_app(),
|
|
29
|
+
name="modules",
|
|
30
|
+
)
|
|
31
|
+
app.command(name="set-config-param")(set_config_parameter)
|
|
32
|
+
app.command("import")(import_to_odoo)
|
|
33
|
+
|
|
34
|
+
return app
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
import typer
|
|
4
|
+
from godoo_rpc.login import wait_for_odoo
|
|
5
|
+
|
|
6
|
+
from ...cli_common import CommonCLI
|
|
7
|
+
|
|
8
|
+
CLI = CommonCLI()
|
|
9
|
+
LOGGER = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@CLI.arg_annotator
|
|
13
|
+
def set_config_parameter(
|
|
14
|
+
param_name: str = typer.Argument(..., help=r"name of ir.config.parameter"),
|
|
15
|
+
param_value: str = typer.Argument(..., help="Value to set config parameter to (:unlink to delete the parameter)"),
|
|
16
|
+
rpc_host=CLI.rpc.rpc_host,
|
|
17
|
+
rpc_database=CLI.rpc.rpc_db_name,
|
|
18
|
+
rpc_user=CLI.rpc.rpc_user,
|
|
19
|
+
rpc_password=CLI.rpc.rpc_password,
|
|
20
|
+
):
|
|
21
|
+
"""Create/Set/Delete ir.config_parameter in Odoo"""
|
|
22
|
+
|
|
23
|
+
odoo_api = wait_for_odoo(
|
|
24
|
+
odoo_host=rpc_host,
|
|
25
|
+
odoo_db=rpc_database,
|
|
26
|
+
odoo_user=rpc_user,
|
|
27
|
+
odoo_password=rpc_password,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
paramteter_model = odoo_api.session.env["ir.config_parameter"]
|
|
31
|
+
|
|
32
|
+
param_id = paramteter_model.search([("key", "=", param_name)])
|
|
33
|
+
param = paramteter_model.browse(param_id[0]) if param_id else None
|
|
34
|
+
|
|
35
|
+
if param_value == ":unlink":
|
|
36
|
+
if param:
|
|
37
|
+
LOGGER.warning("Removing Config Parameter: %s", param_name)
|
|
38
|
+
param.unlink()
|
|
39
|
+
else:
|
|
40
|
+
LOGGER.info("Param '%s' does not exist", param_name)
|
|
41
|
+
return
|
|
42
|
+
|
|
43
|
+
if param:
|
|
44
|
+
LOGGER.info("Setting param value for %s", param_name)
|
|
45
|
+
param.value = param_value
|
|
46
|
+
else:
|
|
47
|
+
LOGGER.info("Creating new Config Parameter: %s", param_name)
|
|
48
|
+
paramteter_model.create({"key": param_name, "value": param_value})
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Import read_path into Odoo.
|
|
3
|
+
Will wait until Odoo is Online.
|
|
4
|
+
Places Systemparam to Track if import was already done.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import List
|
|
10
|
+
|
|
11
|
+
import typer
|
|
12
|
+
from godoo_rpc import import_data
|
|
13
|
+
from godoo_rpc.login import wait_for_odoo
|
|
14
|
+
|
|
15
|
+
from ...cli_common import CommonCLI
|
|
16
|
+
|
|
17
|
+
CLI = CommonCLI()
|
|
18
|
+
LOGGER = logging.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@CLI.unpacker
|
|
22
|
+
@CLI.arg_annotator
|
|
23
|
+
def import_to_odoo(
|
|
24
|
+
read_paths: List[Path] = typer.Argument(
|
|
25
|
+
...,
|
|
26
|
+
readable=True,
|
|
27
|
+
exists=True,
|
|
28
|
+
help="Folder in which to search for import",
|
|
29
|
+
),
|
|
30
|
+
rpc_host=CLI.rpc.rpc_host,
|
|
31
|
+
rpc_database=CLI.rpc.rpc_db_name,
|
|
32
|
+
rpc_user=CLI.rpc.rpc_user,
|
|
33
|
+
rpc_password=CLI.rpc.rpc_password,
|
|
34
|
+
file_regex: str = typer.Option(
|
|
35
|
+
r"(?P<module>.*)\.(csv|py|xlsx|json)$",
|
|
36
|
+
help="Regex for filesearch. Add group 'module' to set a Module for RPC import",
|
|
37
|
+
),
|
|
38
|
+
product_image_regex: str = typer.Option(
|
|
39
|
+
r"(?P<default_code>\d{6})\.(jpeg|png|jpg)$",
|
|
40
|
+
help="Regex to search for Product images. Add Fields as regex group for Matching.",
|
|
41
|
+
),
|
|
42
|
+
check_data_timestamp: bool = typer.Option(
|
|
43
|
+
True,
|
|
44
|
+
help="If true, Odoo remembers the Name of an uploaded File in a Serverparameter. Subsequent Imports will ignore the file if it hasnt changed.",
|
|
45
|
+
),
|
|
46
|
+
skip_existing_ids: bool = typer.Option(False, help="Will skip import of already existing External IDs."),
|
|
47
|
+
):
|
|
48
|
+
"""
|
|
49
|
+
Import [bold green]csv, xlsx, json, .py [/bold green] files into Odoo.
|
|
50
|
+
Adds an ir.config_parameter containing timestamp of each imported file.
|
|
51
|
+
"""
|
|
52
|
+
odoo_api = wait_for_odoo(
|
|
53
|
+
odoo_host=rpc_host,
|
|
54
|
+
odoo_db=rpc_database,
|
|
55
|
+
odoo_user=rpc_user,
|
|
56
|
+
odoo_password=rpc_password,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
if missing_paths := [p for p in read_paths if not p.exists()]:
|
|
60
|
+
raise ValueError("Provided import Paths: %s doesn't exist", ", ".join(missing_paths))
|
|
61
|
+
|
|
62
|
+
for path in read_paths:
|
|
63
|
+
import_data(
|
|
64
|
+
odoo_api=odoo_api,
|
|
65
|
+
read_path=path.absolute(),
|
|
66
|
+
data_regex=file_regex,
|
|
67
|
+
product_image_regex=False if path.is_file() else product_image_regex,
|
|
68
|
+
check_dataset_timestamp=check_data_timestamp,
|
|
69
|
+
skip_existing_ids=skip_existing_ids,
|
|
70
|
+
)
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Any, List
|
|
3
|
+
|
|
4
|
+
import typer
|
|
5
|
+
from godoo_rpc import OdooApiWrapper
|
|
6
|
+
from godoo_rpc.login import wait_for_odoo
|
|
7
|
+
|
|
8
|
+
from ...cli_common import CommonCLI
|
|
9
|
+
|
|
10
|
+
CLI = CommonCLI()
|
|
11
|
+
LOGGER = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def rpc_get_modules(odoo_api: OdooApiWrapper, module_query: str, valid_module_names: List[str] = None):
|
|
15
|
+
"""Get ir.module.module records by a query search string.
|
|
16
|
+
|
|
17
|
+
Parameters
|
|
18
|
+
----------
|
|
19
|
+
odoo_api : OdooApiWrapper
|
|
20
|
+
Odoo Wrapper
|
|
21
|
+
module_query : str
|
|
22
|
+
Custom query. Module name. Comma sep list of modules or % wildcards are supported
|
|
23
|
+
valid_module_names : List[str], optional
|
|
24
|
+
only allow certain model names to be returned, by default None
|
|
25
|
+
|
|
26
|
+
Returns
|
|
27
|
+
-------
|
|
28
|
+
_type_
|
|
29
|
+
_description_
|
|
30
|
+
"""
|
|
31
|
+
mod_env = odoo_api.session.env["ir.module.module"]
|
|
32
|
+
mod_env.update_list()
|
|
33
|
+
|
|
34
|
+
base_domain = []
|
|
35
|
+
if "," in module_query:
|
|
36
|
+
search_domain = [("name", "in", module_query.split(","))]
|
|
37
|
+
else:
|
|
38
|
+
if "%" in module_query:
|
|
39
|
+
search_domain = [("name", "=ilike", module_query)]
|
|
40
|
+
else:
|
|
41
|
+
search_domain = [("name", "=", module_query)]
|
|
42
|
+
|
|
43
|
+
if valid_module_names:
|
|
44
|
+
base_domain.insert(1, "&")
|
|
45
|
+
base_domain.append(("name", "in", valid_module_names))
|
|
46
|
+
|
|
47
|
+
LOGGER.debug("Searching for Modules with Domain: %s", base_domain + search_domain)
|
|
48
|
+
if ids := mod_env.search(base_domain + search_domain):
|
|
49
|
+
modules = mod_env.browse(ids)
|
|
50
|
+
LOGGER.debug("Found Modules: %s", [(m.id, m.name, m.state) for m in modules])
|
|
51
|
+
return modules
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def rpc_install_modules(
|
|
55
|
+
modules: Any,
|
|
56
|
+
upgrade: bool = True,
|
|
57
|
+
):
|
|
58
|
+
"""Install and upgrade Modules to Database.
|
|
59
|
+
|
|
60
|
+
Parameters
|
|
61
|
+
----------
|
|
62
|
+
modules : Iterable RPC ir.module.module records
|
|
63
|
+
List of
|
|
64
|
+
upgrade : bool, optional
|
|
65
|
+
Upgrade module if already installed, by default True
|
|
66
|
+
"""
|
|
67
|
+
did_something = False
|
|
68
|
+
install_module_ids = [m.id for m in modules if m.state == "uninstalled"]
|
|
69
|
+
if install_module_ids:
|
|
70
|
+
install_modules = modules.browse(install_module_ids)
|
|
71
|
+
LOGGER.info("Installing Module: " + ", ".join(install_modules.mapped("name")))
|
|
72
|
+
install_modules.button_immediate_install()
|
|
73
|
+
did_something = True
|
|
74
|
+
|
|
75
|
+
if upgrade and (
|
|
76
|
+
up_module_ids := [m.id for m in modules if m.state == "installed" and m.id not in install_module_ids]
|
|
77
|
+
):
|
|
78
|
+
up_modules = modules.browse(up_module_ids)
|
|
79
|
+
LOGGER.info("Updating Module: " + ", ".join(up_modules.mapped("name")))
|
|
80
|
+
up_modules.button_immediate_upgrade()
|
|
81
|
+
did_something = True
|
|
82
|
+
return did_something
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@CLI.arg_annotator
|
|
86
|
+
def install_modules(
|
|
87
|
+
module_name_query: str = typer.Argument(
|
|
88
|
+
..., help=r"Module Internal name(s), comma seperated. Will use ilike Match if \% is present"
|
|
89
|
+
),
|
|
90
|
+
rpc_host=CLI.rpc.rpc_host,
|
|
91
|
+
rpc_database=CLI.rpc.rpc_db_name,
|
|
92
|
+
rpc_user=CLI.rpc.rpc_user,
|
|
93
|
+
rpc_password=CLI.rpc.rpc_password,
|
|
94
|
+
upgrade: bool = typer.Option(True, help="Upgrae Module if already installed"),
|
|
95
|
+
):
|
|
96
|
+
"""Install or upgrade Odoo modules via RPC. Can act on multiple modules with % wildcard"""
|
|
97
|
+
|
|
98
|
+
odoo_api = wait_for_odoo(
|
|
99
|
+
odoo_host=rpc_host,
|
|
100
|
+
odoo_db=rpc_database,
|
|
101
|
+
odoo_user=rpc_user,
|
|
102
|
+
odoo_password=rpc_password,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
if modules := rpc_get_modules(odoo_api, module_name_query):
|
|
106
|
+
if rpc_install_modules(modules, upgrade=upgrade):
|
|
107
|
+
return
|
|
108
|
+
else:
|
|
109
|
+
LOGGER.warn("Found Modules, but didn't do anything on DB.")
|
|
110
|
+
else:
|
|
111
|
+
LOGGER.warn("Could not find modules with Query: '%s'", module_name_query)
|
|
112
|
+
return CLI.returner(1)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@CLI.arg_annotator
|
|
116
|
+
def uninstall_modules(
|
|
117
|
+
module_name_query: str = typer.Argument(
|
|
118
|
+
..., help=r"Module Internal name(s), comma seperated. Will use ilike Match if \% is present"
|
|
119
|
+
),
|
|
120
|
+
rpc_host=CLI.rpc.rpc_host,
|
|
121
|
+
rpc_database=CLI.rpc.rpc_db_name,
|
|
122
|
+
rpc_user=CLI.rpc.rpc_user,
|
|
123
|
+
rpc_password=CLI.rpc.rpc_password,
|
|
124
|
+
):
|
|
125
|
+
"""Uninstall odoo Modules via RPC. Can act on multiple modules with % wildcard"""
|
|
126
|
+
|
|
127
|
+
odoo_api = wait_for_odoo(
|
|
128
|
+
odoo_host=rpc_host,
|
|
129
|
+
odoo_db=rpc_database,
|
|
130
|
+
odoo_user=rpc_user,
|
|
131
|
+
odoo_password=rpc_password,
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
if modules := rpc_get_modules(odoo_api, module_name_query):
|
|
135
|
+
uninstall_module_ids = [m.id for m in modules if m.state == "installed"]
|
|
136
|
+
if uninstall_module_ids:
|
|
137
|
+
uninstall_modules = modules.browse(uninstall_module_ids)
|
|
138
|
+
LOGGER.info("Uninstalling Module: " + ", ".join(uninstall_modules.mapped("name")))
|
|
139
|
+
uninstall_modules.button_immediate_uninstall()
|
|
140
|
+
else:
|
|
141
|
+
LOGGER.warn("Found Modules, but didn't do anything on DB.")
|
|
142
|
+
else:
|
|
143
|
+
LOGGER.warn("Could not find modules with Query: '%s'", module_name_query)
|
|
144
|
+
return CLI.returner(1)
|