comparison sat/bridge/bridge_constructor/base_constructor.py @ 3028:ab2696e34d29

Python 3 port: /!\ this is a huge commit /!\ starting from this commit, SàT is needs Python 3.6+ /!\ SàT maybe be instable or some feature may not work anymore, this will improve with time This patch port backend, bridge and frontends to Python 3. Roughly this has been done this way: - 2to3 tools has been applied (with python 3.7) - all references to python2 have been replaced with python3 (notably shebangs) - fixed files not handled by 2to3 (notably the shell script) - several manual fixes - fixed issues reported by Python 3 that where not handled in Python 2 - replaced "async" with "async_" when needed (it's a reserved word from Python 3.7) - replaced zope's "implements" with @implementer decorator - temporary hack to handle data pickled in database, as str or bytes may be returned, to be checked later - fixed hash comparison for password - removed some code which is not needed anymore with Python 3 - deactivated some code which needs to be checked (notably certificate validation) - tested with jp, fixed reported issues until some basic commands worked - ported Primitivus (after porting dependencies like urwid satext) - more manual fixes
author Goffi <goffi@goffi.org>
date Tue, 13 Aug 2019 19:08:41 +0200
parents 003b8b4b56a7
children a1bc34f90fa5
comparison
equal deleted inserted replaced
3027:ff5bcb12ae60 3028:ab2696e34d29
1 #!/usr/bin/env python2 1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*- 2 # -*- coding: utf-8 -*-
3 3
4 # SàT: a XMPP client 4 # SàT: a XMPP client
5 # Copyright (C) 2009-2019 Jérôme Poisson (goffi@goffi.org) 5 # Copyright (C) 2009-2019 Jérôme Poisson (goffi@goffi.org)
6 6
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19
20 """base constructor class""" 20 """base constructor class"""
21 21
22 from sat.bridge.bridge_constructor.constants import Const as C 22 from sat.bridge.bridge_constructor.constants import Const as C
23 from ConfigParser import NoOptionError 23 from configparser import NoOptionError
24 import sys 24 import sys
25 import os 25 import os
26 import os.path 26 import os.path
27 import re 27 import re
28 from importlib import import_module 28 from importlib import import_module
189 attr_string = [] 189 attr_string = []
190 190
191 for arg in self.argumentsParser(signature): 191 for arg in self.argumentsParser(signature):
192 attr_string.append( 192 attr_string.append(
193 ( 193 (
194 "unicode(%(name)s)%(default)s" 194 "str(%(name)s)%(default)s"
195 if (unicode_protect and arg == "s") 195 if (unicode_protect and arg == "s")
196 else "%(name)s%(default)s" 196 else "%(name)s%(default)s"
197 ) 197 )
198 % { 198 % {
199 "name": name[idx][0] if (name and idx in name) else "arg_%i" % idx, 199 "name": name[idx][0] if (name and idx in name) else "arg_%i" % idx,
238 try: 238 try:
239 if side == "core": 239 if side == "core":
240 method = self.generateCoreSide 240 method = self.generateCoreSide
241 elif side == "frontend": 241 elif side == "frontend":
242 if not self.FRONTEND_ACTIVATE: 242 if not self.FRONTEND_ACTIVATE:
243 print(u"This constructor only handle core, please use core side") 243 print("This constructor only handle core, please use core side")
244 sys.exit(1) 244 sys.exit(1)
245 method = self.generateFrontendSide 245 method = self.generateFrontendSide
246 except AttributeError: 246 except AttributeError:
247 self._generate(side) 247 self._generate(side)
248 else: 248 else:
269 parts = {part.upper(): [] for part in FORMATS} 269 parts = {part.upper(): [] for part in FORMATS}
270 sections = self.bridge_template.sections() 270 sections = self.bridge_template.sections()
271 sections.sort() 271 sections.sort()
272 for section in sections: 272 for section in sections:
273 function = self.getValues(section) 273 function = self.getValues(section)
274 print("Adding %s %s" % (section, function["type"])) 274 print(("Adding %s %s" % (section, function["type"])))
275 default = self.getDefault(section) 275 default = self.getDefault(section)
276 arg_doc = self.getArgumentsDoc(section) 276 arg_doc = self.getArgumentsDoc(section)
277 async_ = "async" in self.getFlags(section) 277 async_ = "async" in self.getFlags(section)
278 completion = { 278 completion = {
279 "sig_in": function["sig_in"] or "", 279 "sig_in": function["sig_in"] or "",
289 extend_method = getattr( 289 extend_method = getattr(
290 self, "{}_completion_{}".format(side, function["type"]) 290 self, "{}_completion_{}".format(side, function["type"])
291 ) 291 )
292 extend_method(completion, function, default, arg_doc, async_) 292 extend_method(completion, function, default, arg_doc, async_)
293 293
294 for part, fmt in FORMATS.iteritems(): 294 for part, fmt in FORMATS.items():
295 if part.startswith(function["type"]): 295 if part.startswith(function["type"]):
296 parts[part.upper()].append(fmt.format(**completion)) 296 parts[part.upper()].append(fmt.format(**completion))
297 297
298 # at this point, signals_part, methods_part and direct_calls should be filled, 298 # at this point, signals_part, methods_part and direct_calls should be filled,
299 # we just have to place them in the right part of the template 299 # we just have to place them in the right part of the template
300 bridge = [] 300 bridge = []
301 const_override = { 301 const_override = {
302 env[len(C.ENV_OVERRIDE) :]: v 302 env[len(C.ENV_OVERRIDE) :]: v
303 for env, v in os.environ.iteritems() 303 for env, v in os.environ.items()
304 if env.startswith(C.ENV_OVERRIDE) 304 if env.startswith(C.ENV_OVERRIDE)
305 } 305 }
306 template_path = self.getTemplatePath(TEMPLATE) 306 template_path = self.getTemplatePath(TEMPLATE)
307 try: 307 try:
308 with open(template_path) as template: 308 with open(template_path) as template:
309 for line in template: 309 for line in template:
310 310
311 for part, extend_list in parts.iteritems(): 311 for part, extend_list in parts.items():
312 if line.startswith("##{}_PART##".format(part)): 312 if line.startswith("##{}_PART##".format(part)):
313 bridge.extend(extend_list) 313 bridge.extend(extend_list)
314 break 314 break
315 else: 315 else:
316 # the line is not a magic part replacement 316 # the line is not a magic part replacement
317 if line.startswith("const_"): 317 if line.startswith("const_"):
318 const_name = line[len("const_") : line.find(" = ")].strip() 318 const_name = line[len("const_") : line.find(" = ")].strip()
319 if const_name in const_override: 319 if const_name in const_override:
320 print("const {} overriden".format(const_name)) 320 print(("const {} overriden".format(const_name)))
321 bridge.append( 321 bridge.append(
322 "const_{} = {}".format( 322 "const_{} = {}".format(
323 const_name, const_override[const_name] 323 const_name, const_override[const_name]
324 ) 324 )
325 ) 325 )
326 continue 326 continue
327 bridge.append(line.replace("\n", "")) 327 bridge.append(line.replace("\n", ""))
328 except IOError: 328 except IOError:
329 print("can't open template file [{}]".format(template_path)) 329 print(("can't open template file [{}]".format(template_path)))
330 sys.exit(1) 330 sys.exit(1)
331 331
332 # now we write to final file 332 # now we write to final file
333 self.finalWrite(DEST, bridge) 333 self.finalWrite(DEST, bridge)
334 334
346 try: 346 try:
347 if not os.path.exists(self.args.dest_dir): 347 if not os.path.exists(self.args.dest_dir):
348 os.mkdir(self.args.dest_dir) 348 os.mkdir(self.args.dest_dir)
349 full_path = os.path.join(self.args.dest_dir, filename) 349 full_path = os.path.join(self.args.dest_dir, filename)
350 if os.path.exists(full_path) and not self.args.force: 350 if os.path.exists(full_path) and not self.args.force:
351 print( 351 print((
352 "The destination file [%s] already exists ! Use --force to overwrite it" 352 "The destination file [%s] already exists ! Use --force to overwrite it"
353 % full_path 353 % full_path
354 ) 354 ))
355 try: 355 try:
356 with open(full_path, "w") as dest_file: 356 with open(full_path, "w") as dest_file:
357 dest_file.write("\n".join(file_buf)) 357 dest_file.write("\n".join(file_buf))
358 except IOError: 358 except IOError:
359 print("Can't open destination file [%s]" % full_path) 359 print(("Can't open destination file [%s]" % full_path))
360 except OSError: 360 except OSError:
361 print("It's not possible to generate the file, check your permissions") 361 print("It's not possible to generate the file, check your permissions")
362 exit(1) 362 exit(1)