In [ ]:
from os import chdir
chdir('C:\\sandboxes\\django-xmi\\django_xmi')
In [ ]:
from xmi.parser import XmiParser, DotDict, camel_to_snake, make_name_safe
In [ ]:
sysml = XmiParser()
In [ ]:
sysml.parse('../notebooks/UML.xmi')
In [ ]:
sysml.parse('../notebooks/SysML.xmi')
In [ ]:
sysml.parse_profile(sysml.packages.SysML)
In [ ]:
sysml.parse_profile(sysml.packages.UML, 'Package')
In [ ]:
sysml.process_literals()
In [ ]:
sysml.process_attributes()
In [ ]:
sysml.process_operations_and_rules()
In [ ]:
from os import path, remove
from textwrap import wrap
from warnings import warn
In [ ]:
for element_name in self.ordered_elements():
element = self.elements.get(element_name, None)
if element is None:
warn("Could not find '{}' in order to write it to a file".format(element_name))
continue
element.__classdec__ = ['class {}(models.Model):'.format(element.name)]
docstring = element.get('__docstring__', '')
if isinstance(docstring, str):
element.__docstring__ = ([INDENT + '"""'] +
[(INDENT + s) for s in wrap('{}'.format(docstring), 108)] +
[INDENT + '"""\n'])
if isinstance(element.__package__, str):
element.__package__ = [INDENT + "__package__ = '{}'\n".format(element.__package__)]
# Get fields and operations from superclasses:
element.__fields__ = {}
element.__methods__ = {}
element.__literals__ = {}
if inherit:
elem_attrs = element.get('attributes', {}).keys()
elem_methods = set(element.get('rules', {}).keys()).union(set(element.get('operations', {}).keys()))
elem_literals = element.get('literals', {}).keys()
for superclass in element.__modelclass__.split(','):
superclass = self.elements.get(camel_to_snake(superclass.strip()), None)
if superclass is not None:
element.__fields__.update({k: v for k, v in superclass.__fields__.items() if k not in elem_attrs})
element.__methods__.update({k: v for k, v in superclass.__methods__.items() if k not in elem_attrs})
element.__literals__.update({k: v for k, v in superclass.__literals__.items() if k not in elem_attrs})
else:
for i, other in enumerate(element.__modelclass__.split(',')):
other = other.strip()
if 'models.Model' in other:
continue
args = ["'{}'".format(other)]
if i == 0:
args += ['on_delete=models.CASCADE', 'primary_key=True']
var_name = make_name_safe(other)
if var_name in element.__fields__:
warn("\n\tOverwriting field '{}.{}'\n".format(element.name, var_name))
element.__fields__.update({var_name: ' {} = models.OneToOneField({})'.format(var_name, ', '.join(args))})
first = False
for attr in element.get('attributes', {}).values():
if attr.name in element.__fields__:
warn("\n\tOverwriting field '{}.{}'\n".format(element.name, attr.name))
if '__print__' not in attr:
warn("Could not find __print__ method in '{}.{}'".format(element.name, attr.name))
continue
args = ', '.join(attr.__print__.args + [attr.__print__.get('help_text', '')])
element.__fields__.update({attr.name: "{}({})".format(attr.__print__.field, args)})
if '__choices__' in attr:
if attr.name in element.__literals__:
warn("\n\tOverwriting literal '{}.{}'\n".format(element.name, attr.name))
element.__literals__.update({attr.name: attr.__choices__})
for method_name, method in {**element.get('operations', {}), **element.get('rules', {})}.items():
if method_name in element.__methods__:
warn("\n\tOverwriting method '{}.{}'\n".format(element.name, method_name))
if '__print__' not in method:
warn("Could not find __print__ method in '{}.{}'".format(element.name, method_name))
element.__methods__.update({method_name: '\n'.join(method.__print__)})
In [ ]:
for element in sysml.elements.values():
literals = []
if element.__literals__:
literals = ['\n'.join(('\n'+i[-1]+'\n') for i in sorted(element.__literals__.items()))]
element.__django_model__ = (element.__classdec__ +
element.__docstring__ +
element.__package__ +
literals +
[i[1] for i in sorted(element.__fields__.items())] +
['\n' + i[1] for i in sorted(element.__methods__.items())])
In [ ]:
BASE_DIR = './models'
self = sysml
In [ ]:
filenames = set(e.__profile__ for e in self.elements.values())
filenames = {f: path.join(BASE_DIR, f.lower() +'.py') for f in filenames}
for file in filenames.values():
if path.exists(file):
remove(file)
loaded = {}
for elem_name in self.ordered_elements():
element = self.elements.get(elem_name)
filename = filenames[element.__profile__]
with open(filename, 'a') as file:
if filename not in loaded:
file.write('from django.db import models\n')
for module in loaded.values():
file.write('from .{} import *\n'.format(module))
loaded[filename] = element.__profile__.lower()
file.write('\n\n' + '\n'.join(element.__django_model__))
In [ ]:
from shutil import copyfile
copyfile('./models/uml.py', '../../cortex-django/cortex/cerebral/models/uml.py')
copyfile('./models/sysml.py', '../../cortex-django/cortex/cerebral/models/sysml.py')
In [ ]:
sysml.elements.opaque_behavior.attributes.body.ownedComment
Namespace.named_element: (fields.E302) Reverse accessor for 'Namespace.named_element' clashes with field name 'NamedElement.namespace'.
IGNORED_ACCESSORS
set is a workaround to handle this, need a better way to handle it though.