def clean_name(cls, name): prefix, name = cls.get_prefix_name(name) return mapName(cleanupName(name))
def init_fields_(cls, supermod_, modtypes_): cls.supermod_ = supermod_ pk_ = cls.pk() cls.index_spec() fields_idx = cls.fields_idx.keys() if sys.version_info.major == 3: fields_idx = list(fields_idx) if cls.superclass: fields_idx.append(cls.superclass.model_name()) if cls.subclass: fields_idx.append(cls.subclass.model_name()) if cls.fields_idx and pk_ and pk_ not in cls.fields_idx: fields_idx.append(pk_) cls.unique_field_map = make_unique_name_map(fields_idx) cols_attrs = dict() # detect sa type for spec in cls.member_data_items_: sa_name = cls.clean_name(spec.get_name()) child_attrs = spec.get_child_attrs() or dict() data_type = spec.get_data_type() prefix, data_type = cls.get_prefix_name(data_type) if data_type in modtypes_.Defined_simple_type_table: data_type = modtypes_.Defined_simple_type_table[data_type] prefix, data_type = cls.get_prefix_name(data_type.type_name) clean_data_type = mapName(cleanupName(data_type)) if data_type == AnyTypeIdentifier: data_type = 'string' opts = dict() if spec.get_optional(): opts['nullable'] = True sa_data = dict( sa_name=sa_name, sqlname=cls.unique_field_map.get(sa_name), clean_data_type=clean_data_type, data_type=data_type, options=opts, ) if data_type in Simple_type_table: sa_type = 'UnicodeText' if sys.version_info.major == 2: sorted_type_table_items = sorted_type_table.iteritems() else: sorted_type_table_items = sorted_type_table.items() for key, value in sorted_type_table_items: table, alias, parser = value if data_type in table: sa_type = key break else: sys.stderr.write('Unhandled simple type: %s %s\n' % ( sa_name, data_type, )) sa_data.update(sa_type=sa_type, ) else: minOccurs = child_attrs.get(u'minOccurs', '') minOccurs = int(minOccurs) if minOccurs.isdigit() else 0 maxOccurs = child_attrs.get(u'maxOccurs', '') maxOccurs = int(maxOccurs) if maxOccurs.isdigit() else 99999 sa_data.update( minOccurs=minOccurs, maxOccurs=maxOccurs, ) cols_attrs[sa_name] = sa_data cls.set_columns(cols_attrs)
def generate_model_(cls, wrtmodels, unique_name_map, class_suffixes, implicit_many2ones): if class_suffixes: model_suffix = '_model' else: model_suffix = '' class_name = unique_name_map.get(cls.__name__) odoo_class_name = class_name.replace('Type', '') # TODO regexp replace field_prefix = "%s_%s__" % (Lib_name, odoo_class_name.lower()) wrtmodels('\nclass %s%s(sped.SpedBase):\n' % ( odoo_class_name, model_suffix, )) if cls.__doc__: wrtmodels(' _description = """%s"""\n' % (cls.__doc__, )) wrtmodels(" _name = '%s.%s.%s'\n" % ( Lib_name, Version, odoo_class_name.lower(), )) wrtmodels(" _generateds_type = '%s'\n" % (cls.__name__)) wrtmodels(" _concrete_impls = []\n\n") # if cls.superclass is not None: # wrtmodels(' %s = models.ForeignKey("%s%s")\n' % ( # cls.superclass.__name__, cls.superclass.__name__, # model_suffix, )) if class_name in implicit_many2ones: comodel = implicit_many2ones[class_name][0][0] target_field = implicit_many2ones[class_name][0][1] wrtmodels(' %s%s_%s_id = fields.Many2one("%s.%s.%s")\n' % (field_prefix, comodel, target_field, Lib_name, Version, comodel.lower())) choice_selectors = {} for spec in cls.member_data_items_: name = spec.get_name() choice = spec.get_choice() if choice != None: if choice not in choice_selectors.keys(): choice_selectors[choice] = [] choice_selectors[choice].append(name) for k, v in choice_selectors.items(): # TODO can we have a better label? wrtmodels(""" %schoice_selector%s = fields.Selection( %s, "%s", default="%s%s")\n""" % (field_prefix, k, [("%s%s" % (field_prefix, i), i) for i in v], "select%s" % (k, ), field_prefix, v[0])) for spec in cls.member_data_items_: name = spec.get_name() choice = spec.get_choice() prefix, name = cls.get_prefix_name(name) data_type = spec.get_data_type() is_optional = spec.get_optional() prefix, data_type = cls.get_prefix_name(data_type) if data_type in Defined_simple_type_table: data_type = ( Defined_simple_type_table[data_type]).get_type_name_() name = mapName(cleanupName(name)) if name == 'id': name += 'x' elif name.endswith('_') and not name == AnyTypeIdentifier: name += 'x' field_name = "%s%s" % (field_prefix, name) clean_data_type = mapName(cleanupName(data_type)) if data_type == AnyTypeIdentifier: data_type = 'string' string, help_attr, select = cls.extract_string_help_select(spec) if is_optional: options = 'string="""%s"""' % (string, ) else: options = 'string="""%s""", xsd_required=True' % (string, ) if choice != None: options = """choice='%s',\n %s""" % (choice, options) options_nohelp = options if help_attr: options = "%s,\n %s" % ( options, help_attr, ) if data_type in Simple_type_table: if data_type in Integer_type_table: wrtmodels(' %s = fields.Integer(%s)\n' % ( field_name, options, )) elif data_type in Float_type_table: wrtmodels(' %s = fields.Float(%s)\n' % ( field_name, options, )) elif data_type in Date_type_table: wrtmodels(' %s = fields.Date(%s)\n' % ( field_name, options, )) elif data_type in DateTime_type_table: wrtmodels(' %s = fields.Datetime(%s)\n' % ( field_name, options, )) elif data_type in Time_type_table: sys.stderr.write('Unhandled simple type: %s %s\n' % ( field_name, data_type, )) wrtmodels(' %s = fields.TimeField(%s)\n' % ( field_name, options, )) elif data_type in Boolean_type_table: wrtmodels(' %s = fields.Boolean(%s)\n' % ( field_name, options, )) elif data_type in String_type_table: original_st = spec.get_data_type_chain()[0] if 'TDec_' in spec.get_data_type_chain()[0]: digits = spec.get_data_type_chain()[0][8] options = "digits=%s,\n %s" % (digits, options) wrtmodels(' %s = fields.Monetary(%s)\n' % ( field_name, options, )) elif Defined_simple_type_table.get(original_st) \ and (Defined_simple_type_table[original_st] ).get_enumeration_(): enum_type = Defined_simple_type_table[original_st] enum = enum_type.get_enumeration_() options = "%s,\n help=%s" % ( options_nohelp, enum_type.get_descr_()) wrtmodels( ' %s = fields.Selection(%s,\n %s)\n' % ( field_name, original_st, options, )) else: wrtmodels(' %s = fields.Char(%s)\n' % ( field_name, options, )) # TODO size else: sys.stderr.write('Unhandled simple type: %s %s\n' % ( name, data_type, )) elif not Defined_simple_type_table.get(data_type): mapped_type = unique_name_map.get(clean_data_type) if mapped_type is not None: clean_data_type = mapped_type.replace('Type', '') # TODO regexp replace if spec.get_container() == 0: # name in cls._many2one: wrtmodels(' %s = fields.Many2one("%s.%s.%s",\n' % (field_name, Lib_name, Version, clean_data_type.lower())) wrtmodels(' %s)\n' % (options)) # TODO is ondelete='cascade' really the exception? else: wrtmodels( ' %s = fields.One2many(\n "%s.%s.%s",\n' % (field_name, Lib_name, Version, clean_data_type.lower())) wrtmodels(' "%s_%s__%s_%s_id",\n' % (Lib_name, clean_data_type.lower(), field_name, odoo_class_name)) wrtmodels(" %s,\n" % (options, )) # NOTE can we force at least one unless is_optional? wrtmodels(' )\n') wrtmodels('\n')
def main(): args = sys.argv[1:] try: opts, args = getopt.getopt(args, 'ha:s:', [ 'help', 'no-class-suffixes', 'artificial-primary-key', 'no-table-prefixes', ]) except: usage() options = ProgramOptions() options.class_suffixes = '_model' options.pk_ = {'': 'ID'} options.table_prefix_ = 'table_' for opt, val in opts: if opt in ('-h', '--help'): usage() elif opt == '--no-class-suffixes': options.class_suffixes = '' elif opt in ('-a', '--artificial-primary-key'): model, pk = val.split(',') if ',' in val else ('', val) options.pk_[model] = pk elif opt == '--no-table-prefixes': options.table_prefix_ = '' rargs = range(len(args)) module_names = [ cleanupName(os.path.splitext(os.path.split(arg)[1])[0]) for arg in args ] modelcommon_file_name = 'modelcommon.py' main_file_name = 'main.py' modelcommon_writer = Writer(modelcommon_file_name) main_writer = Writer(main_file_name) wrtmodelcommon = modelcommon_writer.write wrtmain = main_writer.write wrtmodelcommon('\n') wrtmodelcommon('\nimport sqlalchemy as sa') wrtmodelcommon('\nfrom sqlalchemy.ext.declarative import declarative_base') wrtmodelcommon('\n') wrtmodelcommon('\nclass_registry = dict()') wrtmodelcommon( '\nDeclarativeBase = declarative_base(class_registry=class_registry)') wrtmodelcommon('\nmetadata = DeclarativeBase.metadata') wrtmodelcommon('\n') wrtmodelcommon('\nclass ProgramOptions(object):') for key, value in vars(options).items(): wrtmodelcommon('\n %s = %s' % (key, repr(value))) wrtmodelcommon('\noptions = ProgramOptions()') wrtmodelcommon('\n') module_class_names = list() class_names = list() all_class_names = list() sa_attrs = list() for c, module_name in enumerate(module_names): supermod = importlib.import_module('%slib' % module_name) module_class_names = model_filter(supermod, args[c]) class_names.append(module_class_names) all_class_names += [ cls['sa_name'] for cls in module_class_names.values() \ if cls.get('generate', True) ] unique_name_map = generatedssuper.make_unique_name_map(all_class_names) for c, module_name in enumerate(module_names): supermod_ = generate_model(options, module_name, class_names[c], unique_name_map) sa_attrs.append(supermod_.__sa_attrs__) wrtmain('\nimport sys') wrtmain('\nimport importlib') wrtmain('\nfrom generateDS import AnyTypeIdentifier, mapName, cleanupName') wrtmain( '\nfrom modelcommon import sa, metadata, class_registry, options\n') models = ', '.join(['models%d' % c for c in rargs]) supermods = ', '.join(['supermod%d' % c for c in rargs]) modelszip = '[%s]' % \ ', '.join(['(models%d, supermod%d, "%s")' % ( c, c, args[c]) for c in rargs]) for c, module_name in enumerate(module_names): wrtmain('\nsupermod%d = importlib.import_module("%slib")' % (c, module_name)) # wrtmain('\nsupermod%d.__sa_attrs__ = %s' % ( # c, repr(sa_attrs[c]))) wrtmain('\nmodtypes%d = importlib.import_module("%stypes")' % (c, module_name)) wrtmain('\nmodels%d = importlib.import_module("%smodel")' % (c, module_name)) # wrtmain('\nimport %s\n' % models) wrtmain('\nimport generatedssuper\n') wrtmain('\n') wrtmain( '\ndef parseSA(supermod, models, inFileName, dbsession, silence=False):' ) wrtmain('\n parser = None') wrtmain('\n doc = supermod.parsexml_(inFileName, parser)') wrtmain('\n rootNode = doc.getroot()') wrtmain('\n rootTag, rootClass = supermod.get_root_tag(rootNode)') wrtmain('\n if rootClass is None:') wrtmain('\n rootTag = cleanupName(rootTag)') wrtmain('\n rootClass = getattr(supermod, rootTag, None)') wrtmain('\n rootObj = rootClass.factory()') wrtmain('\n rootObj.buildSA(rootNode, models, dbsession, not silence)') wrtmain('\n # Enable Python to collect the space used by the DOM.') wrtmain('\n doc = None') wrtmain('\n if not silence:') wrtmain('\n sys.stdout.write(\'<?xml version="1.0" ?>\')') wrtmain('\n rootObj.export(') wrtmain('\n sys.stdout, 0, name_=rootTag,') wrtmain('\n namespacedef_=\'\',') wrtmain('\n pretty_print=True)') wrtmain('\n return rootObj') wrtmain('\n\n') wrtmain(minidom_parser) wrtmain('\n# activate the database engine') wrtmain('\ntry:') wrtmain('\n from custom_ds import rdbms') wrtmain('\nexcept ImportError:') wrtmain("\n #rdbms = 'sqlite:///:memory:'") wrtmain("\n rdbms = 'sqlite:///test.sqlite'") wrtmain('\n') wrtmain("\nengine = sa.create_engine(rdbms)") wrtmain("\nmetadata.create_all(engine)") wrtmain("\nSession = sa.orm.sessionmaker(bind=engine)") wrtmain("\ndbsession = Session()") wrtmain('\n\n') for c in rargs: wrtmain('\ngeneratedssuper.prepare_(supermod%d, options, %s)\n' % (c, repr(sa_attrs[c]))) # wrtmain('\ngeneratedssuper.init_(supermod%d, modtypes%d, options)\n' % ( # c, c)) wrtmain('\nmodelszip = %s\n' % modelszip) wrtmain('\ntry:') wrtmain('\n from custom_ds import custom_parser') wrtmain( '\n custom_parser(modelszip, class_registry, dbsession, parseSA, options)' ) wrtmain('\nexcept ImportError:') wrtmain('\n for xml in sys.argv[1:]:') wrtmain( '\n parseSA(supermod0, class_registry, xml, dbsession, silence=True)' ) wrtmain('\n dbsession.commit()') wrtmain('\n\n') for writer in (modelcommon_writer, main_writer): writer.close(verbose=True)
def generate_model_(cls, wrtmodels, wrtforms, unique_name_map, class_suffixes, class_name_set, class_back_refs, simpletype_array_size): if class_suffixes: model_suffix = '_model' form_suffix = '_form' else: model_suffix = '' form_suffix = '' class_name = unique_name_map.get(cls.__name__) wrtmodels('\nclass %s%s(models.Model):\n' % ( class_name, model_suffix, )) wrtforms('\nclass %s%s(forms.Form):\n' % ( class_name, form_suffix, )) # if cls.superclass is not None: # wrtmodels( # ' %s = models.ForeignKey(\n' % ( # cls.superclass.__name__,)) # wrtmodels( # ' "%s%s",\n' % ( # cls.superclass.__name__, # model_suffix, )) # wrtmodels( # ' on_delete=models.CASCADE,\n') # wrtmodels( # ' )\n') for key in cls.member_data_items_: spec = cls.member_data_items_[key] name = spec.get_name() prefix, name = cls.get_prefix_name(name) data_type = spec.get_data_type() is_optional = spec.get_optional() container = spec.get_container() msg1 = ' # Multiple simple values stored as JSON array.\n' prefix, data_type = cls.get_prefix_name(data_type) if data_type in Defined_simple_type_table: data_type = Defined_simple_type_table[data_type] prefix, data_type = cls.get_prefix_name(data_type.type_name) name = mapName(cleanupName(name)) name = fixDjangoName(name) clean_data_type = mapName(cleanupName(data_type)) if data_type == AnyTypeIdentifier: data_type = 'string' if data_type in Simple_type_table: if is_optional: options = 'blank=True, null=True, ' else: #options = '' options = 'blank=True, null=True, ' if container: wrtmodels(msg1) wrtmodels(' %s = models.TextField(%s)\n' % ( name, options, )) # wrtmodels( # ' %s = models.CharField' # '(max_length=%d, %s)\n' % ( # name, simpletype_array_size, options, )) if data_type in Integer_type_table: if not container: wrtmodels(' %s = models.IntegerField(%s)\n' % ( name, options, )) wrtforms(' %s = forms.IntegerField(%s)\n' % ( name, options, )) elif data_type in Float_type_table: if not container: wrtmodels(' %s = models.FloatField(%s)\n' % ( name, options, )) wrtforms(' %s = forms.FloatField(%s)\n' % ( name, options, )) elif data_type in Date_type_table: if not container: wrtmodels(' %s = models.DateField(%s)\n' % ( name, options, )) wrtforms(' %s = forms.DateField(%s)\n' % ( name, options, )) elif data_type in DateTime_type_table: if not container: wrtmodels(' %s = models.DateTimeField(%s)\n' % ( name, options, )) wrtforms(' %s = forms.DateTimeField(%s)\n' % ( name, options, )) elif data_type in Time_type_table: if not container: wrtmodels(' %s = models.TimeField(%s)\n' % ( name, options, )) wrtforms(' %s = forms.TimeField(%s)\n' % ( name, options, )) elif data_type in Boolean_type_table: if not container: wrtmodels(' %s = models.NullBooleanField(%s)\n' % ( name, options, )) wrtforms(' %s = forms.NullBooleanField(%s)\n' % ( name, options, )) elif data_type in String_type_table: if not container: wrtmodels(' %s = models.CharField(' 'max_length=1000, %s)\n' % ( name, options, )) wrtforms( ' %s = forms.CharField(max_length=1000, %s)\n' % ( name, options, )) else: sys.stderr.write('Unhandled simple type: %s %s\n' % ( name, data_type, )) else: mapped_type = unique_name_map.get(clean_data_type) if mapped_type is not None: clean_data_type = mapped_type wrtforms(' %s = forms.MultipleChoiceField(%s%s.objects' '.all())\n' % ( name, clean_data_type, model_suffix, )) back_refs = class_back_refs.get(class_name) if back_refs is not None: for origin, destination, optional, container in back_refs: if container: wrtmodels(' {}_model_{} = models.ForeignKey(\n'.format( origin, destination)) else: wrtmodels(' {}_model_{} = models.OneToOneField' '(\n'.format(origin, destination)) wrtmodels(' "{}_model",\n'.format(destination)) wrtmodels(' related_name="{}_model_{}",\n'.format( class_name, origin)) wrtmodels(' on_delete=models.CASCADE,\n') if True: # optional: wrtmodels(' blank=True, null=True,\n') wrtmodels(' )\n') wrtmodels('\n') wrtmodels(' def __str__(self):\n') wrtmodels(' return "id: %s" % (self.id, )\n') wrtmodels('\n')
def generate_model_(cls, wrtmodels, wrtforms, unique_name_map, class_suffixes): if class_suffixes: model_suffix = '_model' form_suffix = '_form' else: model_suffix = '' form_suffix = '' class_name = unique_name_map.get(cls.__name__) wrtmodels('\nclass %s%s(models.Model):\n' % ( class_name, model_suffix, )) wrtforms('\nclass %s%s(forms.Form):\n' % ( class_name, form_suffix, )) if cls.superclass is not None: wrtmodels(' %s = models.ForeignKey(\n' % (cls.superclass.__name__, )) wrtmodels(' "%s%s",\n' % ( cls.superclass.__name__, model_suffix, )) wrtmodels(' on_delete=models.CASCADE,\n') wrtmodels(' )\n') for spec in cls.member_data_items_: name = spec.get_name() prefix, name = cls.get_prefix_name(name) data_type = spec.get_data_type() is_optional = spec.get_optional() prefix, data_type = cls.get_prefix_name(data_type) if data_type in Defined_simple_type_table: data_type = Defined_simple_type_table[data_type] prefix, data_type = cls.get_prefix_name(data_type.type_name) name = mapName(cleanupName(name)) if name == 'id': name += 'x' elif name.endswith('_') and not name == AnyTypeIdentifier: name += 'x' clean_data_type = mapName(cleanupName(data_type)) if data_type == AnyTypeIdentifier: data_type = 'string' if data_type in Simple_type_table: if is_optional: options = 'blank=True, null=True' else: options = '' if data_type in Integer_type_table: wrtmodels(' %s = models.IntegerField(%s)\n' % ( name, options, )) wrtforms(' %s = forms.IntegerField(%s)\n' % ( name, options, )) elif data_type in Float_type_table: wrtmodels(' %s = models.FloatField(%s)\n' % ( name, options, )) wrtforms(' %s = forms.FloatField(%s)\n' % ( name, options, )) elif data_type in Date_type_table: wrtmodels(' %s = models.DateField(%s)\n' % ( name, options, )) wrtforms(' %s = forms.DateField(%s)\n' % ( name, options, )) elif data_type in DateTime_type_table: wrtmodels(' %s = models.DateTimeField(%s)\n' % ( name, options, )) wrtforms(' %s = forms.DateTimeField(%s)\n' % ( name, options, )) elif data_type in Time_type_table: wrtmodels(' %s = models.TimeField(%s)\n' % ( name, options, )) wrtforms(' %s = forms.TimeField(%s)\n' % ( name, options, )) elif data_type in Boolean_type_table: wrtmodels(' %s = models.NullBooleanField(%s)\n' % ( name, options, )) wrtforms(' %s = forms.NullBooleanField(%s)\n' % ( name, options, )) elif data_type in String_type_table: wrtmodels( ' %s = models.CharField(max_length=1000, %s)\n' % ( name, options, )) wrtforms( ' %s = forms.CharField(max_length=1000, %s)\n' % ( name, options, )) else: sys.stderr.write('Unhandled simple type: %s %s\n' % ( name, data_type, )) else: mapped_type = unique_name_map.get(clean_data_type) if mapped_type is not None: clean_data_type = mapped_type wrtmodels(' %s = models.ForeignKey(\n "%s%s",\n' % ( name, clean_data_type, model_suffix, )) wrtmodels(' on_delete=models.CASCADE,\n') wrtmodels(' related_name="{}_{}_{}",\n'.format( class_name, name, clean_data_type, )) if is_optional: wrtmodels(' blank=True, null=True,\n') wrtmodels(' )\n') wrtforms(' %s = forms.MultipleChoiceField(%s%s.objects' '.all())\n' % ( name, clean_data_type, model_suffix, )) wrtmodels('\n') wrtmodels(' def __unicode__(self):\n') wrtmodels(' return "id: %s" % (self.id, )\n') wrtmodels('\n')
def generate(options, schema_file_names): for schema_file_name in schema_file_names: schema_name_stem = cleanupName( os.path.splitext(os.path.split(schema_file_name)[1])[0]) bindings_file_name = '%slib.py' % (schema_name_stem, ) types_file_name = '%stypes.py' % (schema_name_stem, ) model_file_name = '%smodel.py' % (schema_name_stem, ) modelcommon_file_name = 'modelcommon.py' main_file_name = 'main.py' file_names = [ model_file_name, modelcommon_file_name, main_file_name, ] dbg_msg(options, 'schema_name_stem: %s\n' % (schema_name_stem, )) dbg_msg(options, 'bindings_file_name: %s\n' % (bindings_file_name, )) dbg_msg(options, 'types_file_name: %s\n' % (types_file_name, )) if options['force']: for file_name in (bindings_file_name, types_file_name): file_stem = os.path.splitext(file_name)[0] file_names += (glob(file_name) + glob('%s.pyc' % file_stem) + glob('__pycache__/%s.*.pyc' % file_stem)) for file_name in file_names: if not os.path.exists(file_name): continue dbg_msg(options, 'removing: %s\n' % file_name) os.remove(file_name) else: for file_name in file_names: if exists(file_name): return args = ( options['path'], '-f', '-o', '%s' % (bindings_file_name, ), '--member-specs=list', "--external-encoding=utf-8", schema_file_name, ) if not run_cmd(options, args): return args = ( './gends_extract_simple_types.py', '-f', '--outfile', types_file_name, schema_file_name, ) if not run_cmd(options, args): return args = [ './gends_generate_sa.py', ] if not options['class_suffixes']: args.append('--no-class-suffixes') for val in options['artificial-primary-key']: args.append('-a') args.append(val) if not run_cmd(options, args + schema_file_names): return