Mercurial > libervia-backend
annotate libervia/backend/bridge/bridge_constructor/base_constructor.py @ 4309:b56b1eae7994
component email gateway: add multicasting:
XEP-0033 multicasting is now supported both for incoming and outgoing messages. XEP-0033
metadata are converted to suitable Email headers and vice versa.
Email address and JID are both supported, and delivery is done by the gateway when
suitable on incoming messages.
rel 450
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 26 Sep 2024 16:12:01 +0200 |
parents | 4cf98f506269 |
children |
rev | line source |
---|---|
3028 | 1 #!/usr/bin/env python3 |
3137 | 2 |
2085 | 3 |
3480
7550ae9cfbac
Renamed the project from "Salut à Toi" to "Libervia":
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
4 # Libervia: an XMPP client |
3479 | 5 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org) |
2085 | 6 |
7 # This program is free software: you can redistribute it and/or modify | |
8 # it under the terms of the GNU Affero General Public License as published by | |
9 # the Free Software Foundation, either version 3 of the License, or | |
10 # (at your option) any later version. | |
11 | |
12 # This program is distributed in the hope that it will be useful, | |
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 # GNU Affero General Public License for more details. | |
16 | |
17 # You should have received a copy of the GNU Affero General Public License | |
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | |
20 """base constructor class""" | |
21 | |
4071
4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents:
4037
diff
changeset
|
22 from libervia.backend.bridge.bridge_constructor.constants import Const as C |
3028 | 23 from configparser import NoOptionError |
2085 | 24 import sys |
25 import os | |
26 import os.path | |
27 import re | |
28 from importlib import import_module | |
29 | |
30 | |
31 class ParseError(Exception): | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
32 # Used when the signature parsing is going wrong (invalid signature ?) |
2085 | 33 pass |
34 | |
35 | |
36 class Constructor(object): | |
37 NAME = None # used in arguments parsing, filename will be used if not set | |
38 # following attribute are used by default generation method | |
39 # they can be set to dict of strings using python formatting syntax | |
40 # dict keys will be used to select part to replace (e.g. "signals" key will | |
41 # replace ##SIGNALS_PART## in template), while the value is the format | |
42 # keys starting with "signal" will be used for signals, while ones starting with | |
43 # "method" will be used for methods | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
44 # check D-Bus constructor for an example |
2085 | 45 CORE_FORMATS = None |
46 CORE_TEMPLATE = None | |
47 CORE_DEST = None | |
48 FRONTEND_FORMATS = None | |
49 FRONTEND_TEMPLATE = None | |
50 FRONTEND_DEST = None | |
51 | |
3538
c605a0d6506f
bridge (constructor/base_constructor): add `args_no_default` to `completion`
Goffi <goffi@goffi.org>
parents:
3480
diff
changeset
|
52 # set to False if your bridge needs only core |
2087
159250d66407
bridge (constructor): embedded bridge generator:
Goffi <goffi@goffi.org>
parents:
2085
diff
changeset
|
53 FRONTEND_ACTIVATE = True |
159250d66407
bridge (constructor): embedded bridge generator:
Goffi <goffi@goffi.org>
parents:
2085
diff
changeset
|
54 |
2085 | 55 def __init__(self, bridge_template, options): |
56 self.bridge_template = bridge_template | |
57 self.args = options | |
58 | |
59 @property | |
60 def constructor_dir(self): | |
61 constructor_mod = import_module(self.__module__) | |
62 return os.path.dirname(constructor_mod.__file__) | |
63 | |
64 def getValues(self, name): | |
65 """Return values of a function in a dict | |
66 @param name: Name of the function to get | |
67 @return: dict, each key has the config value or None if the value is not set""" | |
68 function = {} | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
69 for option in ["type", "category", "sig_in", "sig_out", "doc"]: |
2085 | 70 try: |
71 value = self.bridge_template.get(name, option) | |
72 except NoOptionError: | |
73 value = None | |
74 function[option] = value | |
75 return function | |
76 | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
77 def get_default(self, name): |
2085 | 78 """Return default values of a function in a dict |
79 @param name: Name of the function to get | |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
80 @return: dict, each key is the integer param number (no key if no default value) |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
81 """ |
2085 | 82 default_dict = {} |
83 def_re = re.compile(r"param_(\d+)_default") | |
84 | |
85 for option in self.bridge_template.options(name): | |
86 match = def_re.match(option) | |
87 if match: | |
88 try: | |
89 idx = int(match.group(1)) | |
90 except ValueError: | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
91 raise ParseError( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
92 "Invalid value [%s] for parameter number" % match.group(1) |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
93 ) |
2085 | 94 default_dict[idx] = self.bridge_template.get(name, option) |
95 | |
96 return default_dict | |
97 | |
98 def getFlags(self, name): | |
99 """Return list of flags set for this function | |
100 | |
101 @param name: Name of the function to get | |
102 @return: List of flags (string) | |
103 """ | |
104 flags = [] | |
105 for option in self.bridge_template.options(name): | |
106 if option in C.DECLARATION_FLAGS: | |
107 flags.append(option) | |
108 return flags | |
109 | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
110 def get_arguments_doc(self, name): |
2085 | 111 """Return documentation of arguments |
112 @param name: Name of the function to get | |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
113 @return: dict, each key is the integer param number (no key if no argument doc), value is a tuple (name, doc) |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
114 """ |
2085 | 115 doc_dict = {} |
116 option_re = re.compile(r"doc_param_(\d+)") | |
117 value_re = re.compile(r"^(\w+): (.*)$", re.MULTILINE | re.DOTALL) | |
118 for option in self.bridge_template.options(name): | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
119 if option == "doc_return": |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
120 doc_dict["return"] = self.bridge_template.get(name, option) |
2085 | 121 continue |
122 match = option_re.match(option) | |
123 if match: | |
124 try: | |
125 idx = int(match.group(1)) | |
126 except ValueError: | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
127 raise ParseError( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
128 "Invalid value [%s] for parameter number" % match.group(1) |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
129 ) |
2085 | 130 value_match = value_re.match(self.bridge_template.get(name, option)) |
131 if not value_match: | |
132 raise ParseError("Invalid value for parameter doc [%i]" % idx) | |
133 doc_dict[idx] = (value_match.group(1), value_match.group(2)) | |
134 return doc_dict | |
135 | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
136 def get_doc(self, name): |
2085 | 137 """Return documentation of the method |
138 @param name: Name of the function to get | |
139 @return: string documentation, or None""" | |
140 if self.bridge_template.has_option(name, "doc"): | |
141 return self.bridge_template.get(name, "doc") | |
142 return None | |
143 | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
144 def arguments_parser(self, signature): |
2085 | 145 """Generator which return individual arguments signatures from a global signature""" |
146 start = 0 | |
147 i = 0 | |
148 | |
149 while i < len(signature): | |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
150 if signature[i] not in [ |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
151 "b", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
152 "y", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
153 "n", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
154 "i", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
155 "x", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
156 "q", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
157 "u", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
158 "t", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
159 "d", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
160 "s", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
161 "a", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
162 ]: |
2085 | 163 raise ParseError("Unmanaged attribute type [%c]" % signature[i]) |
164 | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
165 if signature[i] == "a": |
2085 | 166 i += 1 |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
167 if ( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
168 signature[i] != "{" and signature[i] != "(" |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
169 ): # FIXME: must manage tuples out of arrays |
2085 | 170 i += 1 |
171 yield signature[start:i] | |
172 start = i | |
173 continue # we have a simple type for the array | |
174 opening_car = signature[i] | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
175 assert opening_car in ["{", "("] |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
176 closing_car = "}" if opening_car == "{" else ")" |
2085 | 177 opening_count = 1 |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
178 while True: # we have a dict or a list of tuples |
2085 | 179 i += 1 |
180 if i >= len(signature): | |
181 raise ParseError("missing }") | |
182 if signature[i] == opening_car: | |
183 opening_count += 1 | |
184 if signature[i] == closing_car: | |
185 opening_count -= 1 | |
186 if opening_count == 0: | |
187 break | |
188 i += 1 | |
189 yield signature[start:i] | |
190 start = i | |
191 | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
192 def get_arguments(self, signature, name=None, default=None, unicode_protect=False): |
2085 | 193 """Return arguments to user given a signature |
194 | |
195 @param signature: signature in the short form (using s,a,i,b etc) | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
196 @param name: dictionary of arguments name like given by get_arguments_doc |
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
197 @param default: dictionary of default values, like given by get_default |
2085 | 198 @param unicode_protect: activate unicode protection on strings (return strings as unicode(str)) |
2091
f413bfc24458
bridge, quick_frontend: preparation for async bridge
Goffi <goffi@goffi.org>
parents:
2087
diff
changeset
|
199 @return (str): arguments that correspond to a signature (e.g.: "sss" return "arg1, arg2, arg3") |
2085 | 200 """ |
201 idx = 0 | |
202 attr_string = [] | |
203 | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
204 for arg in self.arguments_parser(signature): |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
205 attr_string.append( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
206 ( |
3028 | 207 "str(%(name)s)%(default)s" |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
208 if (unicode_protect and arg == "s") |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
209 else "%(name)s%(default)s" |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
210 ) |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
211 % { |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
212 "name": name[idx][0] if (name and idx in name) else "arg_%i" % idx, |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
213 "default": "=" + default[idx] if (default and idx in default) else "", |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
214 } |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
215 ) |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
216 # give arg_1, arg2, etc or name1, name2=default, etc. |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
217 # give unicode(arg_1), unicode(arg_2), etc. if unicode_protect is set and arg is a string |
2085 | 218 idx += 1 |
219 | |
220 return ", ".join(attr_string) | |
221 | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
222 def get_template_path(self, template_file): |
2085 | 223 """return template path corresponding to file name |
224 | |
225 @param template_file(str): name of template file | |
226 """ | |
227 return os.path.join(self.constructor_dir, template_file) | |
228 | |
229 def core_completion_method(self, completion, function, default, arg_doc, async_): | |
230 """override this method to extend completion""" | |
231 pass | |
232 | |
233 def core_completion_signal(self, completion, function, default, arg_doc, async_): | |
234 """override this method to extend completion""" | |
235 pass | |
236 | |
237 def frontend_completion_method(self, completion, function, default, arg_doc, async_): | |
238 """override this method to extend completion""" | |
239 pass | |
240 | |
241 def frontend_completion_signal(self, completion, function, default, arg_doc, async_): | |
242 """override this method to extend completion""" | |
243 pass | |
244 | |
245 def generate(self, side): | |
246 """generate bridge | |
247 | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
248 call generate_core_side or generateFrontendSide if they exists |
2085 | 249 else call generic self._generate method |
250 """ | |
251 try: | |
252 if side == "core": | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
253 method = self.generate_core_side |
2085 | 254 elif side == "frontend": |
2087
159250d66407
bridge (constructor): embedded bridge generator:
Goffi <goffi@goffi.org>
parents:
2085
diff
changeset
|
255 if not self.FRONTEND_ACTIVATE: |
3028 | 256 print("This constructor only handle core, please use core side") |
2087
159250d66407
bridge (constructor): embedded bridge generator:
Goffi <goffi@goffi.org>
parents:
2085
diff
changeset
|
257 sys.exit(1) |
2085 | 258 method = self.generateFrontendSide |
259 except AttributeError: | |
260 self._generate(side) | |
261 else: | |
262 method() | |
263 | |
264 def _generate(self, side): | |
265 """generate the backend | |
266 | |
267 this is a generic method which will use formats found in self.CORE_SIGNAL_FORMAT | |
268 and self.CORE_METHOD_FORMAT (standard format method will be used) | |
269 @param side(str): core or frontend | |
270 """ | |
271 side_vars = [] | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
272 for var in ("FORMATS", "TEMPLATE", "DEST"): |
2085 | 273 attr = "{}_{}".format(side.upper(), var) |
274 value = getattr(self, attr) | |
275 if value is None: | |
276 raise NotImplementedError | |
277 side_vars.append(value) | |
278 | |
279 FORMATS, TEMPLATE, DEST = side_vars | |
280 del side_vars | |
281 | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
282 parts = {part.upper(): [] for part in FORMATS} |
2085 | 283 sections = self.bridge_template.sections() |
284 sections.sort() | |
285 for section in sections: | |
286 function = self.getValues(section) | |
3028 | 287 print(("Adding %s %s" % (section, function["type"]))) |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
288 default = self.get_default(section) |
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
289 arg_doc = self.get_arguments_doc(section) |
2085 | 290 async_ = "async" in self.getFlags(section) |
291 completion = { | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
292 "sig_in": function["sig_in"] or "", |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
293 "sig_out": function["sig_out"] or "", |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
294 "category": "plugin" if function["category"] == "plugin" else "core", |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
295 "name": section, |
2087
159250d66407
bridge (constructor): embedded bridge generator:
Goffi <goffi@goffi.org>
parents:
2085
diff
changeset
|
296 # arguments with default values |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
297 "args": self.get_arguments( |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
298 function["sig_in"], name=arg_doc, default=default |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
299 ), |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
300 "args_no_default": self.get_arguments(function["sig_in"], name=arg_doc), |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
301 } |
2085 | 302 |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
303 extend_method = getattr( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
304 self, "{}_completion_{}".format(side, function["type"]) |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
305 ) |
2085 | 306 extend_method(completion, function, default, arg_doc, async_) |
307 | |
3028 | 308 for part, fmt in FORMATS.items(): |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
309 if part.startswith(function["type"]) or part.startswith( |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
310 f"async_{function['type']}" |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
311 ): |
2085 | 312 parts[part.upper()].append(fmt.format(**completion)) |
313 | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
314 # at this point, signals_part, methods_part and direct_calls should be filled, |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
315 # we just have to place them in the right part of the template |
2085 | 316 bridge = [] |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
317 const_override = { |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
318 env[len(C.ENV_OVERRIDE) :]: v |
3028 | 319 for env, v in os.environ.items() |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
320 if env.startswith(C.ENV_OVERRIDE) |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
321 } |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
322 template_path = self.get_template_path(TEMPLATE) |
2085 | 323 try: |
324 with open(template_path) as template: | |
325 for line in template: | |
326 | |
3028 | 327 for part, extend_list in parts.items(): |
4280
4cf98f506269
bridge(constructor): fix template parsing, which was broken following `black` reformating.
Goffi <goffi@goffi.org>
parents:
4270
diff
changeset
|
328 if line.lstrip().startswith("##{}_PART##".format(part)): |
2085 | 329 bridge.extend(extend_list) |
330 break | |
331 else: | |
332 # the line is not a magic part replacement | |
4280
4cf98f506269
bridge(constructor): fix template parsing, which was broken following `black` reformating.
Goffi <goffi@goffi.org>
parents:
4270
diff
changeset
|
333 if line.lstrip().startswith("const_"): |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
334 const_name = line[len("const_") : line.find(" = ")].strip() |
2085 | 335 if const_name in const_override: |
3028 | 336 print(("const {} overriden".format(const_name))) |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
337 bridge.append( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
338 "const_{} = {}".format( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
339 const_name, const_override[const_name] |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
340 ) |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
341 ) |
2085 | 342 continue |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
343 bridge.append(line.replace("\n", "")) |
2085 | 344 except IOError: |
3028 | 345 print(("can't open template file [{}]".format(template_path))) |
2085 | 346 sys.exit(1) |
347 | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
348 # now we write to final file |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
349 self.final_write(DEST, bridge) |
2085 | 350 |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
351 def final_write(self, filename, file_buf): |
2085 | 352 """Write the final generated file in [dest dir]/filename |
353 | |
354 @param filename: name of the file to generate | |
355 @param file_buf: list of lines (stings) of the file | |
356 """ | |
357 if os.path.exists(self.args.dest_dir) and not os.path.isdir(self.args.dest_dir): | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
358 print( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
359 "The destination dir [%s] can't be created: a file with this name already exists !" |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
360 ) |
2085 | 361 sys.exit(1) |
362 try: | |
363 if not os.path.exists(self.args.dest_dir): | |
364 os.mkdir(self.args.dest_dir) | |
365 full_path = os.path.join(self.args.dest_dir, filename) | |
366 if os.path.exists(full_path) and not self.args.force: | |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
367 print( |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
368 ( |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
369 "The destination file [%s] already exists ! Use --force to overwrite it" |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
370 % full_path |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
371 ) |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
372 ) |
2085 | 373 try: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
374 with open(full_path, "w") as dest_file: |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
375 dest_file.write("\n".join(file_buf)) |
2085 | 376 except IOError: |
3028 | 377 print(("Can't open destination file [%s]" % full_path)) |
2085 | 378 except OSError: |
379 print("It's not possible to generate the file, check your permissions") | |
380 exit(1) |