agx-openplx 0.15.10__cp312-cp312-manylinux_2_39_x86_64.whl
Sign up to get free protection for your applications and to get access to all the features.
- agx_openplx-0.15.10.dist-info/METADATA +67 -0
- agx_openplx-0.15.10.dist-info/RECORD +41 -0
- agx_openplx-0.15.10.dist-info/WHEEL +4 -0
- agx_openplx-0.15.10.dist-info/entry_points.txt +8 -0
- openplx/Core.py +7781 -0
- openplx/DriveTrain.py +8972 -0
- openplx/Math.py +5372 -0
- openplx/Physics.py +39861 -0
- openplx/Physics1D.py +5534 -0
- openplx/Physics3D.py +39782 -0
- openplx/Robotics.py +14922 -0
- openplx/Simulation.py +1056 -0
- openplx/Terrain.py +3891 -0
- openplx/Urdf.py +654 -0
- openplx/Vehicles.py +8793 -0
- openplx/Visuals.py +3901 -0
- openplx/_AgxOpenPlxPyApi.cpython-312-x86_64-linux-gnu.so +0 -0
- openplx/_CorePythonSwig.cpython-312-x86_64-linux-gnu.so +0 -0
- openplx/_DriveTrainSwig.cpython-312-x86_64-linux-gnu.so +0 -0
- openplx/_MathSwig.cpython-312-x86_64-linux-gnu.so +0 -0
- openplx/_Physics1DSwig.cpython-312-x86_64-linux-gnu.so +0 -0
- openplx/_Physics3DSwig.cpython-312-x86_64-linux-gnu.so +0 -0
- openplx/_PhysicsSwig.cpython-312-x86_64-linux-gnu.so +0 -0
- openplx/_RoboticsSwig.cpython-312-x86_64-linux-gnu.so +0 -0
- openplx/_SimulationSwig.cpython-312-x86_64-linux-gnu.so +0 -0
- openplx/_TerrainSwig.cpython-312-x86_64-linux-gnu.so +0 -0
- openplx/_UrdfSwig.cpython-312-x86_64-linux-gnu.so +0 -0
- openplx/_VehiclesSwig.cpython-312-x86_64-linux-gnu.so +0 -0
- openplx/_VisualsSwig.cpython-312-x86_64-linux-gnu.so +0 -0
- openplx/__init__.py +55 -0
- openplx/agxtoopenplx.py +55 -0
- openplx/anytoopenplx.py +44 -0
- openplx/api.py +1353 -0
- openplx/migrate.py +190 -0
- openplx/migration_hint.py +14 -0
- openplx/migrations.py +703 -0
- openplx/openplx_application.py +138 -0
- openplx/openplx_serialize.py +35 -0
- openplx/openplx_validate.py +57 -0
- openplx/openplx_view.py +14 -0
- openplx/versionaction.py +11 -0
openplx/migrate.py
ADDED
@@ -0,0 +1,190 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
Command line utility that helps migrating OpenPLX files to a newer version
|
4
|
+
"""
|
5
|
+
from pathlib import Path
|
6
|
+
import itertools
|
7
|
+
import os
|
8
|
+
import tempfile
|
9
|
+
import json
|
10
|
+
import urllib.request
|
11
|
+
import zipfile
|
12
|
+
from io import BytesIO
|
13
|
+
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter, SUPPRESS
|
14
|
+
import agx
|
15
|
+
from openplx import __version__, get_error_strings
|
16
|
+
from openplx.Core import OpenPlxContext, parseFromFile, analyze, StringVector, DocumentVector
|
17
|
+
from openplx.migrations import collect_migrations, ReplaceOp, split_version
|
18
|
+
from openplx.versionaction import VersionAction
|
19
|
+
from openplx import register_plugins
|
20
|
+
|
21
|
+
def download_package_version(package_name, version):
|
22
|
+
"""Download a specific version of a package from PyPI."""
|
23
|
+
url = f"https://pypi.org/pypi/{package_name}/{version}/json"
|
24
|
+
with urllib.request.urlopen(url, timeout=16) as response:
|
25
|
+
content = response.read().decode('utf-8')
|
26
|
+
data = json.loads(content)
|
27
|
+
return data['urls'][0]['url']
|
28
|
+
|
29
|
+
|
30
|
+
def unzip_package(url, extract_to):
|
31
|
+
"""Download and unzip a package."""
|
32
|
+
with urllib.request.urlopen(url, timeout=32) as response:
|
33
|
+
file_data = BytesIO(response.read())
|
34
|
+
with zipfile.ZipFile(file_data) as zip_file:
|
35
|
+
zip_file.extractall(extract_to)
|
36
|
+
|
37
|
+
def parse_args():
|
38
|
+
parser = ArgumentParser(description="Migrates a .openplx file from an older to a newer version", formatter_class=ArgumentDefaultsHelpFormatter)
|
39
|
+
parser.add_argument("openplxfile", metavar="path", help="the .openplx file or directory to migrate")
|
40
|
+
parser.add_argument("--version", help="Show version", action=VersionAction, nargs=0, default=SUPPRESS)
|
41
|
+
parser.add_argument("--from-version", help="Version to convert from", required=True)
|
42
|
+
parser.add_argument("--to-version", help="Version to convert to", default=__version__)
|
43
|
+
return parser.parse_known_args()
|
44
|
+
|
45
|
+
def parse_and_analyze(openplxfile, openplx_context):
|
46
|
+
parse_result = parseFromFile(str(Path(openplxfile).absolute()), openplx_context)
|
47
|
+
|
48
|
+
documents = DocumentVector()
|
49
|
+
|
50
|
+
if parse_result[0] is None:
|
51
|
+
return documents
|
52
|
+
|
53
|
+
analyze(openplx_context, None)
|
54
|
+
|
55
|
+
documents.push_back(parse_result[0])
|
56
|
+
return documents
|
57
|
+
|
58
|
+
def has_errors(openplx_context):
|
59
|
+
if openplx_context.hasErrors():
|
60
|
+
error_strings = get_error_strings(openplx_context.getErrors())
|
61
|
+
for e_s in error_strings:
|
62
|
+
print(e_s)
|
63
|
+
return True
|
64
|
+
return False
|
65
|
+
|
66
|
+
def refactor_openplx_file(migration, openplxfile, bundle_path_vec, from_version, to_version) -> bool: # pylint: disable=too-many-locals
|
67
|
+
print(f"Migrating {openplxfile} from {from_version} to {to_version}")
|
68
|
+
file_rename_migrations = []
|
69
|
+
if migration.__name__ == "rename_from_brick_to_openplx":
|
70
|
+
file_rename_migrations.append(migration(openplxfile))
|
71
|
+
if openplxfile.endswith("config.openplx") or openplxfile.endswith("config.brick"):
|
72
|
+
for m in file_rename_migrations:
|
73
|
+
m.apply_to(None, None)
|
74
|
+
return True
|
75
|
+
|
76
|
+
openplx_context = OpenPlxContext(bundle_path_vec)
|
77
|
+
register_plugins(openplx_context, None)
|
78
|
+
documents = parse_and_analyze(openplxfile, openplx_context)
|
79
|
+
|
80
|
+
if has_errors(openplx_context):
|
81
|
+
return False
|
82
|
+
|
83
|
+
if migration.__name__ == "rename_from_brick_to_openplx":
|
84
|
+
for m in file_rename_migrations:
|
85
|
+
m.apply_to(None, None)
|
86
|
+
else:
|
87
|
+
ops = migration(documents)
|
88
|
+
|
89
|
+
for key, op_group in itertools.groupby(ops, lambda op: op.path):
|
90
|
+
if Path(openplxfile).samefile(key):
|
91
|
+
with open(key, 'r', encoding="utf8") as file:
|
92
|
+
lines = file.readlines()
|
93
|
+
replace_ops = [op for op in op_group if isinstance(op, ReplaceOp)]
|
94
|
+
lines = ReplaceOp.apply_many(replace_ops, lines)
|
95
|
+
with open(key, 'w', encoding="utf8") as file:
|
96
|
+
file.writelines(lines)
|
97
|
+
|
98
|
+
return True
|
99
|
+
|
100
|
+
def config_file_path(openplxfile, version):
|
101
|
+
config_file_name = 'config.openplx'
|
102
|
+
if split_version(version) < (0, 15, 0):
|
103
|
+
config_file_name = 'config.brick'
|
104
|
+
if os.path.isdir(openplxfile):
|
105
|
+
return os.path.join(openplxfile, config_file_name)
|
106
|
+
return os.path.join(os.path.dirname(openplxfile), config_file_name)
|
107
|
+
|
108
|
+
def migrate_config_file_versions(config_path, from_version, to_version):
|
109
|
+
bundles = ["Math", "Physics", "Physics1D", "Physics3D",
|
110
|
+
"Robotics", "Urdf", "Terrain", "Vehicles",
|
111
|
+
"Simulation", "Visuals", "DriveTrain"]
|
112
|
+
add_versions = (split_version(from_version) < (0, 11, 0)
|
113
|
+
and split_version(to_version) >= (0, 11, 0))
|
114
|
+
if os.path.exists(config_path):
|
115
|
+
with open(config_path, 'r', encoding="utf8") as file:
|
116
|
+
lines = file.readlines()
|
117
|
+
lines = list(map(lambda line: line.replace(f"=={from_version}", f"=={to_version}"), lines))
|
118
|
+
if add_versions:
|
119
|
+
for i in range(len(lines)): # pylint: disable=consider-using-enumerate
|
120
|
+
for bundle in bundles:
|
121
|
+
lines[i] = lines[i].replace(f"\"{bundle}\"", f"\"{bundle}=={to_version}\"")
|
122
|
+
with open(config_path, 'w', encoding="utf8") as file:
|
123
|
+
file.writelines(lines)
|
124
|
+
|
125
|
+
def run_openplx_migrate_from_version(migration, from_version, to_version, openplxfile): # pylint: disable=too-many-locals
|
126
|
+
package_name = 'openplx-bundles'
|
127
|
+
|
128
|
+
if split_version(from_version) < (0, 15, 0):
|
129
|
+
package_name = 'brickbundles'
|
130
|
+
|
131
|
+
# Download the package
|
132
|
+
url = download_package_version(package_name, from_version)
|
133
|
+
if url is None:
|
134
|
+
print(f"Could not find the source distribution for {package_name}=={from_version}.")
|
135
|
+
return
|
136
|
+
|
137
|
+
# Create a temporary directory
|
138
|
+
with tempfile.TemporaryDirectory() as tmpdirname:
|
139
|
+
tmp_path = str(Path(os.path.realpath(tmpdirname)).absolute())
|
140
|
+
print(f"Extracting to temporary directory: {tmp_path}")
|
141
|
+
unzip_package(url, tmp_path)
|
142
|
+
print(f"Package {package_name}=={from_version} extracted to {tmp_path}")
|
143
|
+
bundle_path = str((Path(tmp_path) / package_name.replace("-", "")).absolute())
|
144
|
+
|
145
|
+
print(f'Using bundle path {bundle_path}')
|
146
|
+
print(os.listdir(bundle_path))
|
147
|
+
|
148
|
+
bundle_path_vec = StringVector()
|
149
|
+
bundle_path_vec.push_back(bundle_path)
|
150
|
+
success = True
|
151
|
+
# Apply the refactoring
|
152
|
+
if os.path.isdir(openplxfile):
|
153
|
+
for root, _, files in os.walk(openplxfile):
|
154
|
+
for file in files:
|
155
|
+
if file.endswith(".openplx") or file.endswith(".brick"):
|
156
|
+
openplxfile = os.path.join(root, file)
|
157
|
+
if not refactor_openplx_file(migration, openplxfile,
|
158
|
+
bundle_path_vec, from_version, to_version):
|
159
|
+
success = False
|
160
|
+
else:
|
161
|
+
if not refactor_openplx_file(migration, openplxfile,
|
162
|
+
bundle_path_vec, from_version, to_version):
|
163
|
+
success = False
|
164
|
+
if success:
|
165
|
+
print(f"Refactor from {from_version} to {to_version} complete!")
|
166
|
+
else:
|
167
|
+
print(f"Refactor from {from_version} to {to_version} failed due to errors!")
|
168
|
+
print("Note, some files might have been partially migrated.")
|
169
|
+
|
170
|
+
|
171
|
+
def run_openplx_migrate(args):
|
172
|
+
migrations = collect_migrations(args.from_version, args.to_version)
|
173
|
+
current_version = args.from_version
|
174
|
+
for migration in migrations:
|
175
|
+
migrate_config_file_versions(config_file_path(args.openplxfile, current_version),
|
176
|
+
current_version, migration.openplx_from_version)
|
177
|
+
run_openplx_migrate_from_version(migration, migration.openplx_from_version,
|
178
|
+
migration.openplx_to_version, args.openplxfile)
|
179
|
+
migrate_config_file_versions(
|
180
|
+
config_file_path(args.openplxfile, migration.openplx_from_version),
|
181
|
+
migration.openplx_from_version, migration.openplx_to_version)
|
182
|
+
current_version = migration.openplx_to_version
|
183
|
+
|
184
|
+
def run():
|
185
|
+
arguments, _ = parse_args()
|
186
|
+
init = agx.AutoInit() # pylint: disable=W0612 # Unused variable 'init'
|
187
|
+
run_openplx_migrate(arguments)
|
188
|
+
|
189
|
+
if __name__ == '__main__':
|
190
|
+
run()
|
@@ -0,0 +1,14 @@
|
|
1
|
+
"""
|
2
|
+
Migration hint for use by cmdline tools
|
3
|
+
"""
|
4
|
+
from openplx import check_if_migrate_hint_is_justified, __version__
|
5
|
+
|
6
|
+
class Ansi: # pylint: disable=too-few-public-methods # This is basically an enum, but we do not want to use Enum
|
7
|
+
WARNING = '\033[93m'
|
8
|
+
ENDC = '\033[0m'
|
9
|
+
|
10
|
+
def check_migration_hint(openplxfile, errors):
|
11
|
+
old_version = check_if_migrate_hint_is_justified(__version__, errors)
|
12
|
+
if old_version:
|
13
|
+
print(f"{Ansi.WARNING}Dependency errors might be due to upgrade. If so, try running: "
|
14
|
+
f"openplx_migrate --from-version {old_version} {openplxfile}{Ansi.ENDC}")
|