bridge(constructor): constructor now uses argparse instead of optparse
This commit is contained in:
parent
001834b760
commit
df1b19bd66
1 changed files with 67 additions and 67 deletions
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env python2
|
||||
#-*- coding: utf-8 -*-
|
||||
|
||||
# SAT: a jabber client
|
||||
# SàT: a XMPP client
|
||||
# Copyright (C) 2009-2016 Jérôme Poisson (goffi@goffi.org)
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
|
|
@ -17,36 +17,38 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#consts
|
||||
NAME = u"bridge_constructor"
|
||||
VERSION = "0.1.0"
|
||||
DEST_DIR = "generated"
|
||||
ABOUT = NAME + u""" v%s (c) Jérôme Poisson (aka Goffi) 2011
|
||||
|
||||
---
|
||||
""" + NAME + u""" Copyright (C) 2011 Jérôme Poisson (aka Goffi)
|
||||
This program comes with ABSOLUTELY NO WARRANTY;
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions.
|
||||
---
|
||||
|
||||
This script construct a SàT bridge using the given protocol
|
||||
"""
|
||||
MANAGED_PROTOCOLES = ['dbus', 'mediawiki', 'dbus-xml']
|
||||
DEFAULT_PROTOCOLE = 'dbus'
|
||||
FLAGS = ['deprecated', 'async']
|
||||
|
||||
ENV_OVERRIDE = "SAT_BRIDGE_CONST_" # Prefix used to override a constant
|
||||
|
||||
from sat.core.constants import Const as C
|
||||
import sys
|
||||
import os
|
||||
from optparse import OptionParser
|
||||
import argparse
|
||||
from ConfigParser import SafeConfigParser as Parser
|
||||
from ConfigParser import NoOptionError
|
||||
import re
|
||||
from datetime import datetime
|
||||
from xml.dom import minidom
|
||||
|
||||
#consts
|
||||
NAME = u"bridge_constructor"
|
||||
__version__ = C.APP_VERSION
|
||||
DEST_DIR_DEFAULT = "generated"
|
||||
DESCRIPTION = u"""{name} Copyright (C) 2009-2016 Jérôme Poisson (aka Goffi)
|
||||
|
||||
This script construct a SàT bridge using the given protocol
|
||||
|
||||
This program comes with ABSOLUTELY NO WARRANTY;
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions.
|
||||
""".format(name=NAME, version=__version__)
|
||||
# TODO: move protocoles in separate files (plugins?)
|
||||
MANAGED_PROTOCOLES = ['dbus', 'mediawiki', 'dbus-xml']
|
||||
DEFAULT_PROTOCOLE = 'dbus'
|
||||
|
||||
# flags used method/signal declaration (not to be confused with constructor flags)
|
||||
DECLARATION_FLAGS = ['deprecated', 'async']
|
||||
|
||||
ENV_OVERRIDE = "SAT_BRIDGE_CONST_" # Prefix used to override a constant
|
||||
|
||||
|
||||
|
||||
class ParseError(Exception):
|
||||
#Used when the signature parsing is going wrong (invalid signature ?)
|
||||
|
|
@ -57,7 +59,7 @@ class Constructor(object):
|
|||
|
||||
def __init__(self, bridge_template, options):
|
||||
self.bridge_template = bridge_template
|
||||
self.options = options
|
||||
self.args = options
|
||||
|
||||
def getValues(self, name):
|
||||
"""Return values of a function in a dict
|
||||
|
|
@ -96,7 +98,7 @@ class Constructor(object):
|
|||
@return: List of flags (string)"""
|
||||
flags = []
|
||||
for option in self.bridge_template.options(name):
|
||||
if option in FLAGS:
|
||||
if option in DECLARATION_FLAGS:
|
||||
flags.append(option)
|
||||
return flags
|
||||
|
||||
|
|
@ -196,17 +198,19 @@ class Constructor(object):
|
|||
raise NotImplementedError
|
||||
|
||||
def finalWrite(self, filename, file_buf):
|
||||
"""Write the final generated file in DEST_DIR/filename
|
||||
"""Write the final generated file in [dest dir]/filename
|
||||
|
||||
@param filename: name of the file to generate
|
||||
@param file_buf: list of lines (stings) of the file"""
|
||||
if os.path.exists(DEST_DIR) and not os.path.isdir(DEST_DIR):
|
||||
@param file_buf: list of lines (stings) of the file
|
||||
"""
|
||||
if os.path.exists(self.args.dest_dir) and not os.path.isdir(self.args.dest_dir):
|
||||
print ("The destination dir [%s] can't be created: a file with this name already exists !")
|
||||
sys.exit(1)
|
||||
try:
|
||||
if not os.path.exists(DEST_DIR):
|
||||
os.mkdir(DEST_DIR)
|
||||
full_path = os.path.join(DEST_DIR, filename)
|
||||
if os.path.exists(full_path) and not self.options.force:
|
||||
if not os.path.exists(self.args.dest_dir):
|
||||
os.mkdir(self.args.dest_dir)
|
||||
full_path = os.path.join(self.args.dest_dir, filename)
|
||||
if os.path.exists(full_path) and not self.args.force:
|
||||
print ("The destination file [%s] already exists ! Use --force to overwrite it" % full_path)
|
||||
try:
|
||||
with open(full_path, 'w') as dest_file:
|
||||
|
|
@ -373,7 +377,7 @@ class DbusConstructor(Constructor):
|
|||
'args': self.getArguments(function['sig_in'], name=arg_doc, default=default)}
|
||||
|
||||
if function["type"] == "signal":
|
||||
completion['body'] = "pass" if not self.options.debug else 'log.debug ("%s")' % section
|
||||
completion['body'] = "pass" if not self.args.debug else 'log.debug ("%s")' % section
|
||||
signals_part.append("""\
|
||||
@dbus.service.signal(const_INT_PREFIX+const_%(category)s_SUFFIX,
|
||||
signature='%(sig_in)s')
|
||||
|
|
@ -386,8 +390,8 @@ class DbusConstructor(Constructor):
|
|||
""" % completion)
|
||||
|
||||
elif function["type"] == "method":
|
||||
completion['debug'] = "" if not self.options.debug else 'log.debug ("%s")\n%s' % (section, 8 * ' ')
|
||||
completion['args_result'] = self.getArguments(function['sig_in'], name=arg_doc, unicode_protect=self.options.unicode)
|
||||
completion['debug'] = "" if not self.args.debug else 'log.debug ("%s")\n%s' % (section, 8 * ' ')
|
||||
completion['args_result'] = self.getArguments(function['sig_in'], name=arg_doc, unicode_protect=self.args.unicode)
|
||||
completion['async_comma'] = ', ' if async and function['sig_in'] else ''
|
||||
completion['async_args_def'] = 'callback=None, errback=None' if async else ''
|
||||
completion['async_args_call'] = 'callback=callback, errback=errback' if async else ''
|
||||
|
|
@ -448,7 +452,7 @@ class DbusConstructor(Constructor):
|
|||
|
||||
if function["type"] == "method":
|
||||
# XXX: we can manage blocking call in the same way as async one: if callback is None the call will be blocking
|
||||
completion['debug'] = "" if not self.options.debug else 'log.debug ("%s")\n%s' % (section, 8 * ' ')
|
||||
completion['debug'] = "" if not self.args.debug else 'log.debug ("%s")\n%s' % (section, 8 * ' ')
|
||||
completion['args_result'] = self.getArguments(function['sig_in'], name=arg_doc)
|
||||
completion['async_args'] = 'callback=None, errback=None'
|
||||
completion['async_comma'] = ', ' if function['sig_in'] else ''
|
||||
|
|
@ -472,7 +476,7 @@ class DbusConstructor(Constructor):
|
|||
"""
|
||||
completion['async_args_result'] = '**kwargs'
|
||||
result = "self.db_%(category)s_iface.%(name)s(%(args_result)s%(async_comma)s%(async_args_result)s)" % completion
|
||||
completion['result'] = ("unicode(%s)" if self.options.unicode and function['sig_out'] == 's' else "%s") % result
|
||||
completion['result'] = ("unicode(%s)" if self.args.unicode and function['sig_out'] == 's' else "%s") % result
|
||||
methods_part.append("""\
|
||||
def %(name)s(self, %(args)s%(async_comma)s%(async_args)s):
|
||||
%(error_handler)s%(blocking_call)s%(debug)sreturn %(result)s
|
||||
|
|
@ -547,7 +551,7 @@ class DbusXmlConstructor(Constructor):
|
|||
_direction = 'in' if function["type"] == 'method' else 'out'
|
||||
arg_elt.setAttribute('direction', _direction)
|
||||
new_elt.appendChild(arg_elt)
|
||||
if "annotation" in self.options.flags:
|
||||
if "annotation" in self.args.flags:
|
||||
if arg in self.default_annotation:
|
||||
annot_elt = doc.createElement("annotation")
|
||||
annot_elt.setAttribute('name', "com.trolltech.QtDBus.QtTypeName.In%d" % idx)
|
||||
|
|
@ -560,7 +564,7 @@ class DbusXmlConstructor(Constructor):
|
|||
arg_elt.setAttribute('type', function['sig_out'])
|
||||
arg_elt.setAttribute('direction', 'out')
|
||||
new_elt.appendChild(arg_elt)
|
||||
if "annotation" in self.options.flags:
|
||||
if "annotation" in self.args.flags:
|
||||
if function['sig_out'] in self.default_annotation:
|
||||
annot_elt = doc.createElement("annotation")
|
||||
annot_elt.setAttribute('name', "com.trolltech.QtDBus.QtTypeName.Out0")
|
||||
|
|
@ -591,48 +595,44 @@ class ConstructorFactory(object):
|
|||
|
||||
class BridgeConstructor(object):
|
||||
def __init__(self):
|
||||
self.options = None
|
||||
self.args = None
|
||||
|
||||
def check_options(self):
|
||||
def parse_args(self):
|
||||
"""Check command line options"""
|
||||
_usage = """
|
||||
%prog [options]
|
||||
parser = argparse.ArgumentParser(description=DESCRIPTION, formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||
|
||||
%prog --help for options list
|
||||
"""
|
||||
parser = OptionParser(usage=_usage, version=ABOUT % VERSION)
|
||||
parser.add_argument("--version", action="version", version= __version__)
|
||||
parser.add_argument("-p", "--protocole", choices=MANAGED_PROTOCOLES, default=DEFAULT_PROTOCOLE,
|
||||
help="generate bridge using PROTOCOLE (default: %(default)s)") # (default: %s, possible values: [%s])" % (DEFAULT_PROTOCOLE, ", ".join(MANAGED_PROTOCOLES)))
|
||||
parser.add_argument("-s", "--side", choices=("core", "frontend"), default="core",
|
||||
help="which side of the bridge do you want to make ?") # (default: %default, possible values: [core, frontend])")
|
||||
parser.add_argument("-t", "--template", type=file, default='bridge_template.ini',
|
||||
help="use TEMPLATE to generate bridge (default: %(default)s)")
|
||||
parser.add_argument("-f", "--force", action="store_true",
|
||||
help=("force overwritting of existing files"))
|
||||
parser.add_argument("-d", "--debug", action="store_true",
|
||||
help=("add debug information printing"))
|
||||
parser.add_argument("--no-unicode", action="store_false", dest="unicode",
|
||||
help=("remove unicode type protection from string results"))
|
||||
parser.add_argument("--flags", nargs='+', default=[],
|
||||
help=("constructors' specific flags"))
|
||||
parser.add_argument("--dest-dir", default=DEST_DIR_DEFAULT,
|
||||
help=("directory when the generated files will be written (default: %(default)s"))
|
||||
|
||||
parser.add_option("-p", "--protocole", action="store", type="string", default=DEFAULT_PROTOCOLE,
|
||||
help="Generate bridge using PROTOCOLE (default: %s, possible values: [%s])" % (DEFAULT_PROTOCOLE, ", ".join(MANAGED_PROTOCOLES)))
|
||||
parser.add_option("-s", "--side", action="store", type="string", default="core",
|
||||
help="Which side of the bridge do you want to make ? (default: %default, possible values: [core, frontend])")
|
||||
parser.add_option("-t", "--template", action="store", type="string", default='bridge_template.ini',
|
||||
help="Use TEMPLATE to generate bridge (default: %default)")
|
||||
parser.add_option("-f", "--force", action="store_true", default=False,
|
||||
help=("Force overwritting of existing files"))
|
||||
parser.add_option("-d", "--debug", action="store_true", default=False,
|
||||
help=("Add debug information printing"))
|
||||
parser.add_option("--no_unicode", action="store_false", dest="unicode", default=True,
|
||||
help=("Remove unicode type protection from string results"))
|
||||
parser.add_option("--flags", action="store", type="string",
|
||||
help=("Constructors' specific flags, comma separated"))
|
||||
|
||||
(self.options, args) = parser.parse_args()
|
||||
self.options.flags = self.options.flags.split(',') if self.options.flags else []
|
||||
return args
|
||||
return parser.parse_args()
|
||||
|
||||
def go(self):
|
||||
self.check_options()
|
||||
args = self.parse_args()
|
||||
self.template = Parser()
|
||||
try:
|
||||
self.template.readfp(open(self.options.template))
|
||||
self.template.readfp(args.template)
|
||||
except IOError:
|
||||
print ("The template file doesn't exist or is not accessible")
|
||||
exit(1)
|
||||
constructor = ConstructorFactory().create(self.template, self.options)
|
||||
if self.options.side == "core":
|
||||
constructor = ConstructorFactory().create(self.template, args)
|
||||
if args.side == "core":
|
||||
constructor.generateCoreSide()
|
||||
elif self.options.side == "frontend":
|
||||
elif args.side == "frontend":
|
||||
constructor.generateFrontendSide()
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
Loading…
Reference in a new issue