e0def4b356803a6fc4a823903eada54001422447
[plstackapi.git] / planetstack / apigen / modelgen
1 #!/usr/bin/python
2
3 import os
4 import pdb
5 import sys
6 import json
7 import re
8 from django.template import Context, Template
9
10 blacklist = ['SingletonModel','PlCoreBase']
11
12 # Django set up
13
14 sys.path.append('.')
15 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "planetstack.settings")
16 from django.db.models.fields.related import ForeignKey, ManyToManyField
17 from core.models import *
18
19 def singular(foo, keys):
20         for k in keys:
21                 if (foo==k+'es'):
22                         return k
23                 elif (foo==k+'s'):
24                         return k
25         raise Exception('Plural to singular error for %s'%foo)
26
27 g = globals()
28
29 def enum_classes():
30         model_classes = []
31         for c in g.values():
32                 if type(c)==type(PlCoreBase) and c.__name__ not in blacklist:
33                         model_classes.append(c)
34         return model_classes
35
36
37 class GenObj(object):
38         def __str__(self):
39                 return str(self.model.__name__.lower())
40
41         def __init__(self, m):
42                 self.model = m
43                 self.props = []
44                 self.refs = []
45
46         def plural(self):
47                 name = str(self)
48                 if (name.endswith('s')):
49                         return name+'es'
50                 else:
51                         return name+'s'
52
53         def camel(self):
54                 name = str(self.model.__name__)
55                 return name
56                 
57 class Generator(dict):
58         def all(self):
59                 return self.values()
60         
61         def regex(self, r):
62                 filtered = filter(lambda o:re.match(r,str(o)), self.values())
63                 return filtered
64
65         def add_object(self, o):
66                 obj = GenObj(o)
67                 fields = o._meta.fields
68                 self[str(obj).lower()]=obj
69
70         def compute_links(self):
71                 for obj in self.values():
72                         if (str(obj).lower()=='user'):
73                                 pdb.set_trace()
74                         fields = obj.model._meta.fields
75                         for f in fields:
76                                 if type(f)==ForeignKey and f.name in self.keys():
77                                         refobj = self[f.name]
78                                         obj.refs.append(refobj)
79                                 else:
80                                         obj.props.append(f.name)
81                         m2m = obj.model._meta.many_to_many
82                         for f in m2m:
83                                 try:
84                                         related_model_name = f.m2m_reverse_field_name()
85                                 except:
86                                         related_model_name = f.m2m_db_table().rsplit('_',1)[-1]
87
88                                 if related_model_name in self.keys():
89                                         refobj = self[related_model_name]
90                                         obj.multi=True
91                                         refobj.refs.append(obj)
92
93                         
94 def main():
95         try:
96                 output = sys.argv[1]
97         except:
98                 print 'Usage: modelgen <output template>'
99                 exit(1)
100
101         generator = Generator()
102
103         models = enum_classes()
104
105         for m in models:
106                 generator.add_object(m)
107
108         generator.compute_links()
109         template_contents = open(output).read()
110         template = Template(template_contents)
111         context = Context({'generator':generator})
112         print template.render(context)
113
114
115 if (__name__=='__main__'):
116         main()