blob: ec08c013107cefca138fa1d22310f4d6bcd7180a [file] [log] [blame]
Sapan Bhatia3a45f8b2014-01-14 21:20:16 -05001#!/usr/bin/python
2
3import os
4import pdb
Sapan Bhatiacdd90b72014-01-28 20:03:13 -05005import copy
Sapan Bhatia3a45f8b2014-01-14 21:20:16 -05006import sys
7import json
8import re
9from django.template import Context, Template
10
Sapan Bhatiadf2b49e2014-01-28 19:41:07 -050011blacklist = ['SingletonModel','PlCoreBase']
12
Sapan Bhatia3a45f8b2014-01-14 21:20:16 -050013# Django set up
14
15sys.path.append('.')
Scott Bakerc63b4f62015-02-16 22:43:01 -080016os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")
Sapan Bhatiaeb62ad62014-01-28 14:29:08 -050017from django.db.models.fields.related import ForeignKey, ManyToManyField
Sapan Bhatia3a45f8b2014-01-14 21:20:16 -050018from core.models import *
19
Sapan Bhatiaeb62ad62014-01-28 14:29:08 -050020def singular(foo, keys):
21 for k in keys:
22 if (foo==k+'es'):
23 return k
24 elif (foo==k+'s'):
25 return k
26 raise Exception('Plural to singular error for %s'%foo)
27
Sapan Bhatia3a45f8b2014-01-14 21:20:16 -050028g = globals()
29
30def enum_classes():
31 model_classes = []
32 for c in g.values():
Sapan Bhatiadf2b49e2014-01-28 19:41:07 -050033 if type(c)==type(PlCoreBase) and c.__name__ not in blacklist:
Sapan Bhatia3a45f8b2014-01-14 21:20:16 -050034 model_classes.append(c)
35 return model_classes
36
37
38class GenObj(object):
39 def __str__(self):
40 return str(self.model.__name__.lower())
41
42 def __init__(self, m):
43 self.model = m
44 self.props = []
45 self.refs = []
Sapan Bhatiabe42fba2014-01-28 23:53:49 -050046 self.plural_name = None
Sapan Bhatia3a45f8b2014-01-14 21:20:16 -050047
48 def plural(self):
Sapan Bhatiabe42fba2014-01-28 23:53:49 -050049 if (self.plural_name):
50 return self.plural_name
Sapan Bhatia3a45f8b2014-01-14 21:20:16 -050051 else:
Sapan Bhatiabe42fba2014-01-28 23:53:49 -050052 name = str(self)
53 if (name.endswith('s')):
54 return name+'es'
55 else:
56 return name+'s'
Sapan Bhatia3a45f8b2014-01-14 21:20:16 -050057
Scott Baker8ffd7d72014-11-10 15:58:58 -080058 def singular(self):
59 return str(self)
60
61 def rest_name(self):
62 # These are things that either for historic reasons or due to incorrect naming,
63 # got called something different than the autogen thinks they should be
64 # called.
Tony Mack336e0f92014-11-30 15:53:08 -050065 REST_FIXUP = {'controllernetworkses': 'controllernetworks',
66 'controllerimageses': 'controllerimages',
67 'controllersliceses': 'controllerslices',
68 'controlleruserses': 'controllerusers',
Scott Baker8ffd7d72014-11-10 15:58:58 -080069 'sitedeploymentses': 'sitedeployments',
70 'siteroles': 'site_roles',
71 'sliceprivileges': 'slice_privileges',
72 'sliceroles': 'slice_roles',
73 }
74 return REST_FIXUP.get(self.plural(), self.plural())
75
Sapan Bhatia3a45f8b2014-01-14 21:20:16 -050076 def camel(self):
77 name = str(self.model.__name__)
Sapan Bhatiadf2b49e2014-01-28 19:41:07 -050078 return name
Sapan Bhatia3a45f8b2014-01-14 21:20:16 -050079
80class Generator(dict):
81 def all(self):
82 return self.values()
83
84 def regex(self, r):
85 filtered = filter(lambda o:re.match(r,str(o)), self.values())
86 return filtered
87
88 def add_object(self, o):
89 obj = GenObj(o)
90 fields = o._meta.fields
91 self[str(obj).lower()]=obj
92
93 def compute_links(self):
94 for obj in self.values():
Sapan Bhatiab5885402014-01-29 10:32:09 -050095 #if (str(obj)=='network'):
Sapan Bhatiacdd90b72014-01-28 20:03:13 -050096 # pdb.set_trace()
Sapan Bhatia3a45f8b2014-01-14 21:20:16 -050097 fields = obj.model._meta.fields
98 for f in fields:
Sapan Bhatiab5885402014-01-29 10:32:09 -050099 if (f and f.rel):
100 to_name = str(f.rel.to)
101 else:
102 to_name = None
103
104 if type(f)==ForeignKey and to_name and to_name in self.keys():
105 refobj = self[f.to_name]
106
107 if (str(obj)=='slice' and f.to_name=='networks'):
108 obj.refs.append(refobj)
Sapan Bhatiabe42fba2014-01-28 23:53:49 -0500109 related_name = f.related_query_name()
Sapan Bhatiab5885402014-01-29 10:32:09 -0500110 if (related_name!='+' and related_name.lower()!=str(obj).lower()):
Sapan Bhatiabe42fba2014-01-28 23:53:49 -0500111 cobj = copy.deepcopy(obj)
112 cobj.multi = True
113 cobj.plural_name = related_name
114 refobj.refs.append(cobj)
Sapan Bhatia3a45f8b2014-01-14 21:20:16 -0500115 else:
116 obj.props.append(f.name)
Sapan Bhatiab5885402014-01-29 10:32:09 -0500117
Sapan Bhatiaeb62ad62014-01-28 14:29:08 -0500118 m2m = obj.model._meta.many_to_many
119 for f in m2m:
120 try:
121 related_model_name = f.m2m_reverse_field_name()
122 except:
123 related_model_name = f.m2m_db_table().rsplit('_',1)[-1]
124
Sapan Bhatiab5885402014-01-29 10:32:09 -0500125 related_name = f.related_query_name()
Sapan Bhatiaeb62ad62014-01-28 14:29:08 -0500126 if related_model_name in self.keys():
Scott Bakerf6404932014-12-15 16:12:43 -0800127 #print "XXX1", obj, f, related_name, related_model_name
Sapan Bhatiaeb62ad62014-01-28 14:29:08 -0500128 refobj = self[related_model_name]
Sapan Bhatiacdd90b72014-01-28 20:03:13 -0500129 cobj = copy.deepcopy(obj)
130 cobj.multi=True
131 refobj.refs.append(cobj)
Scott Baker1e67bb42014-07-03 17:58:10 -0700132
133 # deal with upgradeFrom_rel_+
134 if (related_name.endswith("+")):
135 continue
136
Sapan Bhatiab5885402014-01-29 10:32:09 -0500137 if (related_name!='+' and related_name.lower()!=str(obj).lower()):
Scott Bakerf6404932014-12-15 16:12:43 -0800138 #print "XXX2", obj, f, related_name, related_model_name, refobj.plural_name
139 refobj = self[related_model_name]
140 cobj = copy.deepcopy(refobj)
Sapan Bhatiabe42fba2014-01-28 23:53:49 -0500141 cobj.multi = True
Sapan Bhatiab5885402014-01-29 10:32:09 -0500142
Scott Bakerf6404932014-12-15 16:12:43 -0800143 obj.refs.append(cobj)
Sapan Bhatiab5885402014-01-29 10:32:09 -0500144
Sapan Bhatiabe42fba2014-01-28 23:53:49 -0500145
Sapan Bhatiaeb62ad62014-01-28 14:29:08 -0500146
Sapan Bhatia3a45f8b2014-01-14 21:20:16 -0500147
148def main():
149 try:
150 output = sys.argv[1]
151 except:
152 print 'Usage: modelgen <output template>'
153 exit(1)
154
155 generator = Generator()
156
157 models = enum_classes()
158
159 for m in models:
160 generator.add_object(m)
161
162 generator.compute_links()
163 template_contents = open(output).read()
164 template = Template(template_contents)
165 context = Context({'generator':generator})
166 print template.render(context)
167
168
169if (__name__=='__main__'):
170 main()