blob: 8a647b173339b7d61061e821019079881f88485c [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('.')
16os.environ.setdefault("DJANGO_SETTINGS_MODULE", "planetstack.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.
65 REST_FIXUP = {'networkdeploymentses': 'networkdeployments',
66 'imagedeploymentses': 'imagedeployments',
Scott Baker72bcf352014-11-21 11:36:19 -080067 'slicedeploymentses': 'slicedeployments',
68 'userdeploymentses': 'userdeployments',
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
Sapan Bhatiab5885402014-01-29 10:32:09 -0500114 #if (str(refobj)=='slice' and related_name=='networks'):
115 # pdb.set_trace()
Sapan Bhatiabe42fba2014-01-28 23:53:49 -0500116 refobj.refs.append(cobj)
Sapan Bhatia3a45f8b2014-01-14 21:20:16 -0500117 else:
118 obj.props.append(f.name)
Sapan Bhatiab5885402014-01-29 10:32:09 -0500119
Sapan Bhatiaeb62ad62014-01-28 14:29:08 -0500120 m2m = obj.model._meta.many_to_many
121 for f in m2m:
122 try:
123 related_model_name = f.m2m_reverse_field_name()
124 except:
125 related_model_name = f.m2m_db_table().rsplit('_',1)[-1]
126
Sapan Bhatiab5885402014-01-29 10:32:09 -0500127 related_name = f.related_query_name()
Sapan Bhatiaeb62ad62014-01-28 14:29:08 -0500128 if related_model_name in self.keys():
Sapan Bhatiacdd90b72014-01-28 20:03:13 -0500129 # pdb.set_trace()
Sapan Bhatiaeb62ad62014-01-28 14:29:08 -0500130 refobj = self[related_model_name]
Sapan Bhatiacdd90b72014-01-28 20:03:13 -0500131 cobj = copy.deepcopy(obj)
132 cobj.multi=True
133 refobj.refs.append(cobj)
Scott Baker1e67bb42014-07-03 17:58:10 -0700134
135 # deal with upgradeFrom_rel_+
136 if (related_name.endswith("+")):
137 continue
138
Sapan Bhatiab5885402014-01-29 10:32:09 -0500139 if (related_name!='+' and related_name.lower()!=str(obj).lower()):
Sapan Bhatiabe42fba2014-01-28 23:53:49 -0500140 cobj = copy.deepcopy(obj)
141 cobj.multi = True
142 cobj.plural_name = related_name
Sapan Bhatiab5885402014-01-29 10:32:09 -0500143
144 #if (str(refobj)=='slice' and related_name=='networks'):
145 # pdb.set_trace()
Sapan Bhatia4efd0d92014-01-29 00:20:06 -0500146 refobj.refs.append(cobj)
Sapan Bhatiabe42fba2014-01-28 23:53:49 -0500147
Sapan Bhatiab5885402014-01-29 10:32:09 -0500148 #if (related_name=='networks'):
149 #pdb.set_trace()
150 #print str(refobj)
151
Sapan Bhatiabe42fba2014-01-28 23:53:49 -0500152
Sapan Bhatiaeb62ad62014-01-28 14:29:08 -0500153
Sapan Bhatia3a45f8b2014-01-14 21:20:16 -0500154
155def main():
156 try:
157 output = sys.argv[1]
158 except:
159 print 'Usage: modelgen <output template>'
160 exit(1)
161
162 generator = Generator()
163
164 models = enum_classes()
165
166 for m in models:
167 generator.add_object(m)
168
169 generator.compute_links()
170 template_contents = open(output).read()
171 template = Template(template_contents)
172 context = Context({'generator':generator})
173 print template.render(context)
174
175
176if (__name__=='__main__'):
177 main()