blob: 82de5b13aca74c7673c7517fd9c1c39c33566cd1 [file] [log] [blame]
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -07001import pdb
Sapan Bhatiac4f803f2017-04-21 11:50:39 +02002import re
Sapan Bhatia7886e122017-05-17 11:19:39 +02003from pattern import en
4
Sapan Bhatia943dad52017-05-19 18:41:01 +02005def xproto_unquote(s):
6 return unquote(s)
7
Sapan Bhatia49b54ae2017-05-19 17:11:32 +02008def unquote(s):
9 if (s.startswith('"') and s.endswith('"')):
10 return s[1:-1]
11
12def xproto_singularize(field):
13 try:
14 # The user has set a singular, as an exception that cannot be handled automatically
15 singular = field['options']['singular']
16 singular = unquote(singular)
17 except KeyError:
18 singular = en.singularize(field['name'])
19
20 return singular
21
Sapan Bhatia7886e122017-05-17 11:19:39 +020022def xproto_pluralize(field):
23 try:
24 # The user has set a plural, as an exception that cannot be handled automatically
25 plural = field['options']['plural']
Sapan Bhatia49b54ae2017-05-19 17:11:32 +020026 plural = unquote(plural)
Sapan Bhatia7886e122017-05-17 11:19:39 +020027 except KeyError:
28 plural = en.pluralize(field['name'])
29
30 return plural
Sapan Bhatiac4f803f2017-04-21 11:50:39 +020031
Sapan Bhatia5769d932017-05-17 11:10:54 +020032def xproto_unquote(s):
33 if (s.startswith('"') and s.endswith('"')):
34 s = s[1:-1]
35 return s
36
Sapan Bhatiad022aeb2017-06-07 15:49:55 +020037def xproto_links_to_modeldef_relations(llst):
38 outlist = []
39 seen = []
40 for l in llst:
41 try:
42 t = l['link_type']
43 except KeyError, e:
44 raise e
45
46 if l['peer'] not in seen and t!='manytomany':
47 outlist.append('- {model: %s, type: %s}\n'%(l['peer'], l['link_type']))
48 seen.append(l['peer'])
49
50 return outlist
51
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -070052def django_content_type_string(xptags):
53 # Check possibility of KeyError in caller
54 content_type = xptags['content_type']
55
Sapan Bhatiac4f803f2017-04-21 11:50:39 +020056 try:
57 content_type = eval(content_type)
58 except:
59 pass
60
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -070061 if (content_type=='url'):
62 return 'URLField'
Sapan Bhatiac4f803f2017-04-21 11:50:39 +020063 if (content_type=='date'):
64 return 'DateTimeField'
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -070065 elif (content_type=='ip'):
66 return 'GenericIPAddressField'
67 elif (content_type=='stripped' or content_type=='"stripped"'):
68 return 'StrippedCharField'
Sapan Bhatiac4f803f2017-04-21 11:50:39 +020069 else:
Sapan Bhatia943dad52017-05-19 18:41:01 +020070 raise Exception('Unknown Type: %s'%content_type)
Sapan Bhatia8a57c662017-04-11 10:39:47 -070071
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -070072def django_string_type(xptags):
Sapan Bhatiac4f803f2017-04-21 11:50:39 +020073 try:
74 max_length = eval(xptags['max_length'])
75 except:
76 max_length = 1024 * 1024
77
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -070078 if ('content_type' in xptags):
79 return django_content_type_string(xptags)
Sapan Bhatiac4f803f2017-04-21 11:50:39 +020080 elif (max_length<1024*1024):
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -070081 return 'CharField'
Sapan Bhatiac4f803f2017-04-21 11:50:39 +020082 else:
83 return 'TextField'
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -070084
Sapan Bhatia4e80a262017-05-19 23:10:51 +020085def xproto_base_def(model_name, base):
86 if (model_name=='XOSBase'):
87 return '(models.Model, PlModelMixIn)'
88 elif (not base):
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -070089 return ''
90 else:
91 return '(' + ','.join(base) + ')'
92
Sapan Bhatia504cc972017-04-27 01:56:28 +020093def xproto_first_non_empty(lst):
94 for l in lst:
95 if l: return l
96
Sapan Bhatia943dad52017-05-19 18:41:01 +020097def xproto_api_type(field):
98 try:
99 if (unquote(field['options']['content_type'])=='date'):
100 return 'float'
101 except KeyError:
102 pass
103
104 return field['type']
105
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -0700106def xproto_django_type(xptype, xptags):
107 if (xptype=='string'):
108 return django_string_type(xptags)
109 elif (xptype=='float'):
110 return 'FloatField'
111 elif (xptype=='bool'):
112 return 'BooleanField'
113 elif (xptype=='uint32'):
114 return 'IntegerField'
115 elif (xptype=='int32'):
116 return 'IntegerField'
117 elif (xptype=='int64'):
118 return 'BigIntegerField'
119 else:
120 raise Exception('Unknown Type: %s'%xptype)
121
122
123
124def xproto_django_link_type(f):
125 if (f['link_type']=='manytoone'):
126 return 'ForeignKey'
127 elif (f['link_type']=='manytomany'):
128 if (f['dst_port']):
Sapan Bhatiac4f803f2017-04-21 11:50:39 +0200129 return 'ManyToManyField'
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -0700130 else:
131 return 'GenericRelation'
132
133def format_options_string(d):
134 if (not d):
135 return ''
136 else:
Sapan Bhatiac4f803f2017-04-21 11:50:39 +0200137
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -0700138 lst = []
139 for k,v in d.items():
Sapan Bhatiac4f803f2017-04-21 11:50:39 +0200140 if (type(v)==str and k=='default' and v.endswith('()"')):
141 lst.append('%s = %s'%(k,v[1:-3]))
142 elif (type(v)==str and v.startswith('"')):
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -0700143 try:
144 tup = eval(v[1:-1])
145 if (type(tup)==tuple):
146 lst.append('%s = %r'%(k,tup))
147 else:
148 lst.append('%s = %s'%(k,v))
149 except:
150 lst.append('%s = %s'%(k,v))
151 elif (type(v)==bool):
152 lst.append('%s = %r'%(k,bool(v)))
153 else:
154 try:
155 lst.append('%s = %r'%(k,int(v)))
156 except ValueError:
157 lst.append('%s = %s'%(k,v))
158
159 return ', '.join(lst)
160
161def map_xproto_to_django(f):
Sapan Bhatiad022aeb2017-06-07 15:49:55 +0200162 allowed_keys=['help_text','default','max_length','modifier','blank','choices','db_index','null','editable','on_delete','verbose_name', 'auto_now_add']
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -0700163
164 m = {'modifier':{'optional':True, 'required':False, '_target':'null'}}
165 out = {}
166
167 for k,v in f['options'].items():
168 if (k in allowed_keys):
169 try:
170 kv2 = m[k]
171 out[kv2['_target']] = kv2[v]
172 except:
173 out[k] = v
174 return out
175
176
Sapan Bhatiac4f803f2017-04-21 11:50:39 +0200177def xproto_django_link_options_str(field, dport=None):
178 output_dict = map_xproto_to_django(field)
179
180 if (dport and (dport=='+' or '+' not in dport)):
181 output_dict['related_name'] = '%r'%dport
182
183 try:
Sapan Bhatiaf7662b02017-04-27 01:03:04 +0200184 if field['through']:
185 if not field['through'].endswith('_'+field['name']):
186 output_dict['through'] = '%r'%field['through']
187 except KeyError:
Sapan Bhatiac4f803f2017-04-21 11:50:39 +0200188 pass
189
190 return format_options_string(output_dict)
191
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -0700192def xproto_django_options_str(field, dport=None):
193 output_dict = map_xproto_to_django(field)
194
195 if (dport=='_'):
196 dport = '+'
197
Sapan Bhatiac4f803f2017-04-21 11:50:39 +0200198 if (dport and (dport=='+' or '+' not in dport)):
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -0700199 output_dict['related_name'] = '%r'%dport
Sapan Bhatiac4f803f2017-04-21 11:50:39 +0200200
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -0700201 return format_options_string(output_dict)
Sapan Bhatiac4f803f2017-04-21 11:50:39 +0200202
203def xproto_base_name(n):
204 # Hack - Refactor NetworkParameter* to make this go away
205 if (n.startswith('NetworkParameter')):
206 return '_'
207
Sapan Bhatia4e80a262017-05-19 23:10:51 +0200208 expr = r'^[A-Z]+[a-z]*'
Sapan Bhatiac4f803f2017-04-21 11:50:39 +0200209
210 try:
211 match = re.findall(expr, n)[0]
212 except:
213 return '_'
214
215 return match
Sapan Bhatiaae9645c2017-05-05 15:35:54 +0200216
Sapan Bhatia943dad52017-05-19 18:41:01 +0200217def xproto_base_fields(m, table):
218 fields = []
219
220 for b in m['bases']:
221 if b in table:
222 base_fields = xproto_base_fields(table[b], table)
223
224 model_fields = table[b]['fields']
225 fields.extend(base_fields)
226 fields.extend(model_fields)
227
228 return fields
Sapan Bhatiad022aeb2017-06-07 15:49:55 +0200229
230def xproto_base_links(m, table):
231 links = []
232
233 for b in m['bases']:
234 if b in table:
235 base_links = xproto_base_links(table[b], table)
236
237 model_links = table[b]['links']
238 links.extend(base_links)
239 links.extend(model_links)
240 return links
241
242
243def xproto_validators(f):
244 # To be cleaned up when we formalize validation in xproto
245 validators = []
246
247 # bound-based validators
248 bound_validators = [('max_length','maxlength'), ('min', 'min'), ('max', 'max')]
249
250 for v0, v1 in bound_validators:
251 try:
252 validators.append({'name':v1, 'int_value':f['options'][v0]})
253 except KeyError:
254 pass
255
256 # validators based on content_type
257 content_type_validators = ['ip', 'url', 'email']
258
259 for v in content_type_validators:
260 #if f['name']=='ip': pdb.set_trace()
261 try:
262 val = unquote(f['options']['content_type'])==v
263 if not val:
264 raise KeyError
265
266 validators.append({'name':v, 'bool_value': True})
267 except KeyError:
268 pass
269
270 # required validator
271 try:
272 required = f['options']['blank']=='False' and f['options']['null']=='False'
273 if required:
274 validators.append({'name':'required', 'bool_value':required})
275 except KeyError:
276 pass
277
278 return validators
279
280def xproto_string_type(xptags):
281 try:
282 max_length = eval(xptags['max_length'])
283 except:
284 max_length = 1024
285
286 if ('varchar' not in xptags):
287 return 'string'
288 else:
289 return 'text'
290
291def xproto_type_to_ui_type(f):
292 try:
293 content_type = f['options']['content_type']
294 content_type = eval(content_type)
295 except:
296 content_type = None
297 pass
298
299 if content_type == 'date':
300 return 'date'
301 elif f['type'] == 'bool':
302 return 'boolean'
303 elif f['type'] == 'string':
304 return xproto_string_type(f['options'])
305 elif f['type'] in ['int','uint32','int32'] or 'link' in f:
306 return 'number'
307 elif f['type'] in ['double','float']:
308 return 'string'