blob: c4dc68a1ef23153c127e2241766cd5895a24717b [file] [log] [blame]
#!/usr/bin/python
import os
import pdb
import sys
import json
sys.path.append('.')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")
from django.db.models.fields.related import ForeignKey
# try to make sure we're running from the right place
if (not os.path.exists("core")):
if (os.path.exists("../core")):
os.chdir("..")
else:
print >> sys.stderr, "Are you sure you're running dmdot from the root of an XOS installation"
sys.exit(-1)
from core.models import ModelLink
# defaults
apps = ["core"]#, "services.hpc", "services.requestrouter", "services.onos"]
output = "-json"
# syntax: mldeps [-json | -dot] [app_name]
# poor man's argument parser
for arg in sys.argv[1:]:
if arg.startswith("-"):
output = arg
else:
apps+= [arg]
model_classes = []
class_names = []
lower_class_names = {}
synonyms = {
'user':'creator'
}
for app in apps:
app = app + ".models"
#models_module = imp.load_source(app, ".")
models_module = __import__(app)
for part in app.split(".")[1:]:
if hasattr(models_module, "PlCoreBase"):
break
models_module = getattr(models_module,part)
PlCoreBase = getattr(models_module,"PlCoreBase")
for classname in dir(models_module):
c = getattr(models_module, classname, None)
if type(c)==type(PlCoreBase):
model_classes.append(c)
class_names.append(c.__name__)
lower_class_names[c.__name__.lower()] = c
try:
synonym = synonyms[c.__name__.lower()]
lower_class_names[synonym] = c
except:
pass
# django doesn't use the correct case in field.name.title() for objects that
# have CamelCased class names. So, compare everything in lower case.
if (output=='-dot'):
print "digraph plstack {";
for c in model_classes:
fields = c._meta.fields
for f in fields:
if type(f)==ForeignKey and f.name.lower().split('_') in lower_class_names:
linked_class = lower_class_names[f.name.lower()]
if ('backref' in f.name):
print '\t"%s"->"%s";'%(linked_class.__name__,c.__name__)
else:
print '\t"%s"->"%s";'%(c.__name__,linked_class.__name__)
print "}\n";
elif (output=='-json'):
d = {}
tl = {}
for c in model_classes:
fields = c._meta.fields
try:
exp_links = c.xos_links
except AttributeError:
exp_links = []
for f in fields:
field_type = f.name.lower().split('_')[0]
if type(f)==ForeignKey and field_type in lower_class_names:
linked_class = lower_class_names[field_type]
if ('backref' in f.name.lower()):
a = linked_class.__name__
b = c.__name__
else:
b = linked_class.__name__
a = c.__name__
try:
if (b not in d[a]):
d[a].append(b)
except KeyError:
d[c.__name__]=[linked_class.__name__]
for l in exp_links:
linked_class = l.dest
if (type(linked_class)==str):
linked_class = lower_class_names[linked_class.lower()]
via = l.via
if ('backref' in via):
a = linked_class.__name__
b = c.__name__
else:
b = linked_class.__name__
a = c.__name__
try:
if (b not in tl[a]):
tl[a].append(b)
except KeyError:
tl[c.__name__]=[linked_class.__name__]
#d['ControllerNetwork'].append('SliceDeployments')
print json.dumps(tl,indent=4)