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