CORD-1093: Updated legacy code to xproto converter with several bug
fixes
Change-Id: Ica25711410cf97cc96d7427558c8222b171f7084
diff --git a/xos/tools/apigen/lib.py b/xos/tools/apigen/lib.py
index 70d0ac4..1a7b12e 100644
--- a/xos/tools/apigen/lib.py
+++ b/xos/tools/apigen/lib.py
@@ -76,13 +76,35 @@
return format_options_string(output_dict)
def xp_to_xproto(field, idx):
- t = field.get_internal_type()
+ at = type(field).__name__
+ try:
+ t = field.get_internal_type()
+ except AttributeError:
+ t = type(field).__name__
+
link = False
+ through = None
if (t=='CharField' or t=='TextField' or t=='SlugField'):
xptype = 'string'
elif (t=='BooleanField'):
xptype = 'bool'
+ elif (t=='ManyToManyField'):
+ if (at=='ManyToManyField'):
+ xptype = 'manytomany'
+ peer = field.related.model.__name__
+ through = field.related.model.through
+ if (field.related.name):
+ dst_port = ':' + field.related.name
+ else:
+ dst_port = ''
+ else:
+ xptype = 'manytomany'
+ peer = field.related.model.__name__
+ dst_port = ''
+
+
+ link = True
elif (t=='ForeignKey'):
xptype = 'manytoone'
peer = field.related.model.__name__
@@ -107,7 +129,9 @@
xptype = 'string'
elif (t=='OneToOneField'):
link = True
-
+
+ else:
+ raise Exception('Bad field')
if (field.null==False):
modifier = 'required'
@@ -115,7 +139,12 @@
modifier = 'optional'
if (link):
- str = '%s %s %s->%s%s = %d'%(modifier, xptype, field.name, peer, dst_port, idx)
+ if (through):
+ dst_model = '%s/%s'%(peer,through)
+ else:
+ dst_model = '%s'%peer
+
+ str = '%s %s %s->%s%s = %d'%(modifier, xptype, field.name, dst_model, dst_port, idx)
else:
str = '%s %s %s = %d'%(modifier, xptype, field.name, idx)
diff --git a/xos/tools/apigen/modelgen2 b/xos/tools/apigen/modelgen2
index 916fbe5..b78719a 100755
--- a/xos/tools/apigen/modelgen2
+++ b/xos/tools/apigen/modelgen2
@@ -18,6 +18,7 @@
sys.path.append('/opt/xos')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")
from django.db.models.fields.related import ForeignKey, ManyToManyField
+from django.contrib.contenttypes.fields import GenericRelation
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
@@ -184,7 +185,7 @@
def add_object(self, o):
global app_map
obj = GenObj(o)
- fields = o._meta.fields
+ fields = o._meta.get_fields(include_hidden=False)
try:
obj.app = app_map[o.__name__] # full name
if hasattr(o, "_meta") and hasattr(o._meta, "app_label"):
@@ -208,42 +209,51 @@
except KeyError:
self.apps[obj.app] = {file_name:[obj]}
+
self[str(obj).lower()]=obj
def compute_links(self):
for obj in self.values():
base_props = [f.name for f in obj.model.__base__._meta.fields] + ['id']
- #if (str(obj)=='network'):
- # pdb.set_trace()
- fields = obj.model._meta.fields
+ fields = list(obj.model._meta.fields + obj.model._meta.many_to_many)
+
+ other_fields = obj.model._meta.get_fields()
+ for o in other_fields:
+ if (type(o)==GenericRelation): fields+=[o]
+
+
for f in fields:
- if (f and f.rel):
+ if f.name in base_props or type(f).__name__=='ManyToOneRel': continue
+
+ if (f and hasattr(f, 'rel') and f.rel):
to_name = str(f.rel.to)
else:
to_name = None
- if type(f)==ForeignKey and to_name and to_name in self.keys():
- refobj = self[f.to_name]
- if (str(obj)=='slice' and f.to_name=='networks'):
- obj.refs.append(refobj)
- related_name = f.related_query_name()
- if (related_name!='+' and related_name.lower()!=str(obj).lower()):
- cobj = copy.deepcopy(obj)
- cobj.multi = True
- cobj.plural_name = related_name
- refobj.refs.append(cobj)
- elif f.name.endswith("_ptr"):
+ if f.name.endswith("_ptr"):
# django inherited model, for example HPCService
# cause swagger and REST to break
pass
else:
f.type = f.__class__.__name__
+
if (type(f)==ForeignKey):
f.related.model.class_name = f.related.model.__name__
+ elif (type(f)==ManyToManyField or type(f)==GenericRelation):
+ f.related.model.class_name = f.related.model.__name__
+ try:
+ f.related.model.through = f.related.through.__name__
+ except AttributeError:
+ pass
+
+
if (f.name not in base_props):
obj.fields.append(f)
+
+ #if (f.name == 'tags'): pdb.set_trace()
+
obj.all_fields.append(f)
obj.props.append(f.name)
diff --git a/xos/tools/apigen/xproto.template.txt b/xos/tools/apigen/xproto.template.txt
index 8320443..252e99a 100644
--- a/xos/tools/apigen/xproto.template.txt
+++ b/xos/tools/apigen/xproto.template.txt
@@ -1,7 +1,7 @@
{% for object in generator.all() %}
message {{ object.camel() }} ({%- if (object.bases) -%}{{ object.bases}}){%- endif -%} {
- {%- for field in object.fields %}
+ {%- for field in object.all_fields %}
{{ xp_to_xproto(field, loop.index) }} {{xp_options(field)}};
{%- endfor %}
}