Skip to content

Commit 90b0b89

Browse files
committed
Renamed generator regex filter option to --settings-regex-filter
1 parent ab292dc commit 90b0b89

File tree

2 files changed

+164
-6
lines changed

2 files changed

+164
-6
lines changed

tools/generate-settings-dataclasses-jinja.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -273,27 +273,33 @@ def generate_introspection(root: Element) -> List[NmSettingsIntrospection]:
273273

274274
def main(
275275
settings_xml_path: Path,
276-
regex_filter: Optional[Pattern] = None,
276+
settings_regex_filter: Optional[Pattern] = None,
277277
) -> None:
278278
jinja_env = Environment(
279279
loader=FileSystemLoader(Path('./tools/jinja_templates/')),
280280
)
281281
settings_template = jinja_env.get_template('setting.py.jinja2')
282282

283283
tree = parse(settings_xml_path)
284-
introspection = generate_introspection(tree.getroot())
284+
all_settings = generate_introspection(tree.getroot())
285285

286286
settings_dir = Path('./sdbus_async/networkmanager/settings/')
287-
for setting in introspection:
287+
for setting in all_settings:
288288

289-
if regex_filter is not None:
290-
if not regex_filter.match(setting.snake_name):
289+
if settings_regex_filter is not None:
290+
if not settings_regex_filter.match(setting.snake_name):
291291
continue
292292

293293
setting_py_file = settings_dir / (setting.snake_name + '.py')
294294
with open(setting_py_file, mode='w') as f:
295295
f.write(settings_template.render(setting=setting))
296296

297+
profile_template = jinja_env.get_template('profile.py.jinja2')
298+
with open(settings_dir / 'profile.py', mode='w') as f:
299+
f.write(profile_template.render(
300+
all_settings=sorted(all_settings, key=lambda x: x.snake_name))
301+
)
302+
297303

298304
if __name__ == '__main__':
299305
arg_parser = ArgumentParser()
@@ -303,7 +309,7 @@ def main(
303309
default=Path('./nm-settings-docs-dbus.xml'),
304310
)
305311
arg_parser.add_argument(
306-
'--regex-filter',
312+
'--settings-regex-filter',
307313
type=regex_compile,
308314
)
309315

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# SPDX-License-Identifier: LGPL-2.1-or-later
2+
# This file was generated by tools/generate-settings-dataclasses-jinja.py,
3+
# if possible, please make changes by also updating the script.
4+
from __future__ import annotations
5+
6+
from dataclasses import dataclass, field, fields
7+
from typing import Any, Dict, Optional
8+
9+
from .base import NetworkManagerSettingsMixin
10+
{% for setting in all_settings -%}
11+
from .{{ setting.snake_name }} import {{ setting.python_class_name }}
12+
{% endfor -%}
13+
from ..types import NetworkManagerConnectionProperties, SettingsDict
14+
15+
16+
@dataclass
17+
class ConnectionProfile:
18+
"""
19+
Connection profiles
20+
-------------------
21+
22+
NetworkManager is based on a concept of connection profiles, most often
23+
referred to just as "connections". Connection profiles provide a network
24+
configuration. When NetworkManager activates a connection profile on a
25+
network device, the configuration will be applied and an active network
26+
connection will be established. Users are free to create as many
27+
connection profiles as they see fit. Thus they are flexible in having
28+
various network configurations for different networking needs:
29+
https://networkmanager.pages.freedesktop.org/NetworkManager/NetworkManager/nm-settings-dbus.html
30+
31+
Connection profiles are handled by NetworkManager via a settings service
32+
and are exported on D-Bus (/org/freedesktop/NetworkManager/Settings/<num>)
33+
34+
Definition of a connection profile:
35+
A specific, encapsulated, independent group of settings describing
36+
all the configuration required to connect to a specific network.
37+
38+
It is referred to by a unique identifier called the UUID.
39+
A connection profile is tied to a one specific device type,
40+
but not necessarily a specific hardware device.
41+
42+
A connection profile is composed of one or more Settings objects.
43+
44+
Settings objects
45+
----------------
46+
47+
A group of related key/value pairs describing a specific piece
48+
of a Connection (profile). Keys are also referred to as properties.
49+
"""
50+
# The settings object "connection" is special: It must always be present
51+
# because it contains the UUID and the connection type which are required:
52+
connection: ConnectionSettings = field(
53+
metadata={'dbus_name': 'connection',
54+
'settings_class': ConnectionSettings},
55+
)
56+
# The list of the remaining settings classes was generated by
57+
# tools/generate-settings-dataclasses-jinja.py which generates the
58+
# settings classes themselfes as well.
59+
# If possible, please make changes by also updating the script.
60+
61+
# start of the generated list of settings classes
62+
{%- for setting in all_settings %}
63+
{{ setting.snake_name }}: Optional[{{ setting.python_class_name }}] = field(
64+
metadata={'dbus_name': '{{ setting.name }}',
65+
'settings_class': {{ setting.python_class_name }}},
66+
default=None,
67+
)
68+
{%- endfor %}
69+
# end of the generated list of settings classes
70+
71+
def to_dbus(self) -> NetworkManagerConnectionProperties:
72+
new_dict: NetworkManagerConnectionProperties = {}
73+
74+
for x in fields(self):
75+
value = getattr(self, x.name)
76+
if value is None:
77+
continue
78+
79+
new_dict[x.metadata['dbus_name']] = value.to_dbus()
80+
81+
return new_dict
82+
83+
def to_settings_dict(self, defaults: bool = False) -> SettingsDict:
84+
"""Return a simple dictionary using the same key names like the dbus
85+
dict from to_dbus(), but without the dbus signatures returned by it.
86+
87+
Contrary to dataclasses.asdict(), it provides the orignal dbus keys,
88+
e.g. with numerical prefixes like "802-11-", dashes, and "id"/"type".
89+
90+
The key names provided are exactly as documented in these tables:
91+
https://networkmanager.dev/docs/api/latest/nm-settings-dbus.html
92+
93+
param defaults: Whether properies with default values are returned.
94+
"""
95+
new_dict = {}
96+
for x in fields(self):
97+
settings_class = getattr(self, x.name)
98+
if settings_class:
99+
settingsdomain_dict = settings_class.to_settings_dict(defaults)
100+
if settingsdomain_dict != {}:
101+
new_dict[x.metadata['dbus_name']] = settingsdomain_dict
102+
return new_dict
103+
104+
@property
105+
def dbus_name_to_settings_class(self) -> Dict[str, str]:
106+
return {f.metadata['dbus_name']: f.name
107+
for f in fields(self)}
108+
109+
@classmethod
110+
def from_dbus(cls, dbus_dict: NetworkManagerConnectionProperties
111+
) -> ConnectionProfile:
112+
for domain in ("ipv4", "ipv6"):
113+
group = dbus_dict.get(domain, None)
114+
if group:
115+
for key in ("addresses", "routes"):
116+
group.pop(key, None)
117+
try:
118+
unvarianted_options: Dict[str, Any] = {
119+
SETTING_DBUS_NAME_TO_NAME[k]: SETTING_TO_CLASS[k].from_dbus(v)
120+
for k, v in dbus_dict.items()}
121+
except KeyError as e:
122+
print(dbus_dict)
123+
raise e
124+
return cls(**unvarianted_options)
125+
126+
@classmethod
127+
def from_settings_dict(
128+
cls, settings_dict: SettingsDict
129+
) -> ConnectionProfile:
130+
"""Return a ConnectionProfile created from a simple settings dict
131+
A simple settings dict uses the same keys as from_dbus() and to_dbus()
132+
but without the dbus variable signatures used by NetworkManader.py
133+
134+
This means a simple settings dict does not use the underscore in keys
135+
like the attributes of this class have to use and use "id" and "type".
136+
"""
137+
unvarianted_options: Dict[str, Any] = {
138+
SETTING_DBUS_NAME_TO_NAME[k]: SETTING_TO_CLASS[k].from_dict(v)
139+
for k, v in settings_dict.items()}
140+
return cls(**unvarianted_options)
141+
142+
143+
SETTING_DBUS_NAME_TO_NAME: Dict[str, str] = {
144+
f.metadata['dbus_name']: f.name
145+
for f in fields(ConnectionProfile)
146+
}
147+
148+
SETTING_TO_CLASS: Dict[str, NetworkManagerSettingsMixin] = {
149+
f.metadata['dbus_name']: f.metadata['settings_class']
150+
for f in fields(ConnectionProfile)
151+
}
152+

0 commit comments

Comments
 (0)