blob: 464172ac50e27990a5a373827b3a0c3eb4672bc6 [file] [log] [blame]
Matteo Scandolod2044a42017-08-07 16:08:28 -07001
2# Copyright 2017-present Open Networking Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040017from base import *
18import pdb
Sapan Bhatia1e021772017-08-19 02:15:48 -040019import re
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040020
Sapan Bhatiad8e4a232017-07-12 21:20:06 -040021def django_content_type_string(xptags):
22 # Check possibility of KeyError in caller
23 content_type = xptags['content_type']
24
25 try:
26 content_type = eval(content_type)
27 except:
28 pass
29
30 if (content_type=='url'):
31 return 'URLField'
32 if (content_type=='date'):
33 return 'DateTimeField'
34 elif (content_type=='ip'):
35 return 'GenericIPAddressField'
36 elif (content_type=='stripped' or content_type=='"stripped"'):
37 return 'StrippedCharField'
38 else:
39 raise Exception('Unknown Type: %s'%content_type)
40
41def django_string_type(xptags):
42 try:
43 max_length = eval(xptags['max_length'])
44 except:
45 max_length = 1024 * 1024
46
47 if ('content_type' in xptags):
48 return django_content_type_string(xptags)
49 elif (max_length<1024*1024):
50 return 'CharField'
51 else:
52 return 'TextField'
53
54def xproto_django_type(xptype, xptags):
55 if (xptype=='string'):
56 return django_string_type(xptags)
57 elif (xptype=='float'):
58 return 'FloatField'
59 elif (xptype=='bool'):
60 return 'BooleanField'
61 elif (xptype=='uint32'):
62 return 'IntegerField'
63 elif (xptype=='int32'):
64 return 'IntegerField'
65 elif (xptype=='int64'):
66 return 'BigIntegerField'
67 else:
68 raise Exception('Unknown Type: %s'%xptype)
69
70def xproto_django_link_type(f):
71 if (f['link_type']=='manytoone'):
72 return 'ForeignKey'
Sapan Bhatia9590a882017-08-01 08:35:23 -040073 elif (f['link_type']=='onetoone'):
74 return 'OneToOneField'
Sapan Bhatiad8e4a232017-07-12 21:20:06 -040075 elif (f['link_type']=='manytomany'):
76 if (f['dst_port']):
77 return 'ManyToManyField'
78 else:
79 return 'GenericRelation'
80
81def map_xproto_to_django(f):
Scott Bakereb782fc2018-04-27 13:50:21 -070082 allowed_keys=['help_text','default','max_length','modifier','blank','choices','db_index','null','editable','on_delete','verbose_name', 'auto_now_add', 'unique']
Sapan Bhatiad8e4a232017-07-12 21:20:06 -040083
84 m = {'modifier':{'optional':True, 'required':False, '_target':'null'}}
85 out = {}
86
87 for k,v in f['options'].items():
88 if (k in allowed_keys):
89 try:
90 kv2 = m[k]
91 out[kv2['_target']] = kv2[v]
92 except:
93 out[k] = v
94 return out
95
96def xproto_django_link_options_str(field, dport=None):
97 output_dict = map_xproto_to_django(field)
98
99 if (dport and (dport=='+' or '+' not in dport)):
100 output_dict['related_name'] = '%r'%dport
101
102 try:
103 if field['through']:
104 d = {}
105 if isinstance(field['through'], str):
106 split = field['through'].rsplit('.',1)
107 d['name'] = split[-1]
108 if len(split)==2:
109 d['package'] = split[0]
110 d['fqn'] = 'package' + '.' + d['name']
111 else:
112 d['fqn'] = d['name']
113 d['package'] = ''
114 else:
115 d = field['through']
116
117 if not d['name'].endswith('_'+field['name']):
118 output_dict['through'] = '%r'%d['fqn']
119 except KeyError:
120 pass
121
122 return format_options_string(output_dict)
123
124def format_options_string(d):
125 if (not d):
126 return ''
127 else:
128
129 lst = []
130 for k,v in d.items():
131 if (type(v)==str and k=='default' and v.endswith('()"')):
132 lst.append('%s = %s'%(k,v[1:-3]))
133 elif (type(v)==str and v.startswith('"')):
134 try:
135 tup = eval(v[1:-1])
136 if (type(tup)==tuple):
137 lst.append('%s = %r'%(k,tup))
138 else:
139 lst.append('%s = %s'%(k,v))
140 except:
141 lst.append('%s = %s'%(k,v))
142 elif (type(v)==bool):
143 lst.append('%s = %r'%(k,bool(v)))
144 else:
145 try:
146 lst.append('%s = %r'%(k,int(v)))
147 except ValueError:
148 lst.append('%s = %s'%(k,v))
149
150 return ', '.join(lst)
151
152def xproto_django_options_str(field, dport=None):
153 output_dict = map_xproto_to_django(field)
154
155 if (dport=='_'):
156 dport = '+'
157
158 if (dport and (dport=='+' or '+' not in dport)):
159 output_dict['related_name'] = '%r'%dport
160
161 return format_options_string(output_dict)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400162
Sapan Bhatia1e021772017-08-19 02:15:48 -0400163def xproto_camel_to_underscore(name):
164 return re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
165
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400166def xproto_validations(options):
167 try:
168 return [map(str.strip, validation.split(':')) for validation in unquote(options['validators']).split(',')]
169 except KeyError:
170 return []
Matteo Scandolo23cf15f2018-03-06 18:12:36 -0800171
172def xproto_optioned_fields_to_list(fields, option, val):
173 """
174 List all the field that have a particural option
175 :param fields: (list) an array of message fields
176 :param option: (string) the option to look for
177 :param val: (any) the value of the option
178 :return: list of strings, field names where option is set
179 """
180
181 optioned_fields = []
182 for f in fields:
183 option_names = []
184 for k, v in f['options'].items():
185 option_names.append(k)
186
187 if option in option_names and f['options'][option] == val:
188 optioned_fields.append(f['name'])
189
190 return optioned_fields
191
192# TODO
193# - in modeldefs add info about this fields
194# - update the gui to have this fields as readonly