1 |
1 |
from __future__ import absolute_import
|
2 |
2 |
|
|
3 |
import collections
|
3 |
4 |
import re
|
4 |
5 |
|
5 |
6 |
from django import template
|
|
7 |
from django.utils.html import mark_safe, format_html, conditional_escape, escape
|
|
8 |
from django.utils.translation import ugettext as _
|
6 |
9 |
from django.contrib.contenttypes.models import ContentType
|
7 |
10 |
from django.contrib.auth import get_permission_codename
|
8 |
11 |
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
... | ... | |
84 |
87 |
@stringfilter
|
85 |
88 |
def censor(string):
|
86 |
89 |
return re.sub(r'://([^/]*):([^/]*?)@', r'://\1:***@', string)
|
|
90 |
|
|
91 |
|
|
92 |
def render_json_schema(schema):
|
|
93 |
if not isinstance(schema, dict):
|
|
94 |
if schema is True:
|
|
95 |
return mark_safe('<em>ALWAYS VALID</em>')
|
|
96 |
if schema is False:
|
|
97 |
return mark_safe('<em>ALWAYS INVALID</em>')
|
|
98 |
return format_html('<tt>{!r}</tt>', schema)
|
|
99 |
|
|
100 |
def many_of(name, schemas):
|
|
101 |
s = format_html('<b>{}</b>', name)
|
|
102 |
parts = [render_json_schema(schema) for schema in schemas]
|
|
103 |
if any('\n' in part for part in parts):
|
|
104 |
s += '<ul>'
|
|
105 |
for part in parts:
|
|
106 |
s += format_html('<li>{0}</li>\n', part)
|
|
107 |
s += '</ul>'
|
|
108 |
else:
|
|
109 |
s += ' [ ' + ' | '.join(parts) + ' ]'
|
|
110 |
return mark_safe(s)
|
|
111 |
|
|
112 |
if 'anyOf' in schema:
|
|
113 |
return many_of('anyOf', schema['anyOf'])
|
|
114 |
|
|
115 |
if 'oneOf' in schema:
|
|
116 |
return many_of('oneOf', schema['oneOf'])
|
|
117 |
|
|
118 |
if 'allOf' in schema:
|
|
119 |
return many_of('allOf', schema['allOf'])
|
|
120 |
|
|
121 |
original_schema = schema
|
|
122 |
schema = schema.copy()
|
|
123 |
schema.pop('$schema', None)
|
|
124 |
schema.pop('$id', None)
|
|
125 |
title = schema.pop('title', None)
|
|
126 |
description = schema.pop('description', None)
|
|
127 |
typ = schema.pop('type', None)
|
|
128 |
if typ == 'null':
|
|
129 |
return mark_safe('<b>null</b>')
|
|
130 |
if typ == 'string':
|
|
131 |
enum = schema.pop('enum', [])
|
|
132 |
min_length = schema.pop('minLength', '')
|
|
133 |
max_length = schema.pop('maxLength', '')
|
|
134 |
pattern = schema.pop('pattern', '')
|
|
135 |
if enum:
|
|
136 |
enum = mark_safe(' | '.join(
|
|
137 |
[format_html('"<tt>{}</tt>"', el) for el in enum]))
|
|
138 |
s = '<b>string'
|
|
139 |
if max_length or min_length:
|
|
140 |
s += format_html('[{0}:{1}]', min_length, max_length)
|
|
141 |
s += '</b>'
|
|
142 |
if enum:
|
|
143 |
s += ' %s' % enum
|
|
144 |
if pattern:
|
|
145 |
s += format_html(' /<tt>{}</tt>/', pattern)
|
|
146 |
if schema:
|
|
147 |
s += format_html('\n{!r}', schema)
|
|
148 |
return mark_safe(s)
|
|
149 |
if typ == 'integer':
|
|
150 |
if not schema:
|
|
151 |
return mark_safe('<b>integer</b>')
|
|
152 |
if typ == 'number':
|
|
153 |
if not schema:
|
|
154 |
return mark_safe('<b>number</b>')
|
|
155 |
if typ == 'array':
|
|
156 |
s = '<b>array</b> '
|
|
157 |
if 'items' in schema:
|
|
158 |
s += render_json_schema(schema['items'])
|
|
159 |
return mark_safe(s)
|
|
160 |
if typ == 'object':
|
|
161 |
s = '<b>object</b>'
|
|
162 |
unflatten = schema.pop('unflatten', False)
|
|
163 |
merge_extra = schema.pop('merge_extra', False)
|
|
164 |
properties = schema.pop('properties', {})
|
|
165 |
required_keys = schema.pop('required', [])
|
|
166 |
additional_properties = schema.pop('additionalProperties', True)
|
|
167 |
if unflatten:
|
|
168 |
s += ', <em class="unflatten">unflatten</em>'
|
|
169 |
if merge_extra:
|
|
170 |
s += ', <em class="merge-extra">merge_extra</em>'
|
|
171 |
if not additional_properties:
|
|
172 |
s += ', <em class="additional-properties-false">no additional properties</em>'
|
|
173 |
if title:
|
|
174 |
s += format_html(', <em class="title">{}</em>', title)
|
|
175 |
if schema:
|
|
176 |
s += format_html('<tt class="raw">{!r}</tt>', schema)
|
|
177 |
if description:
|
|
178 |
s += format_html('\n<p class="description">{}</p>', description)
|
|
179 |
s += ' '
|
|
180 |
if properties:
|
|
181 |
s += '\n<ul>'
|
|
182 |
keys = properties
|
|
183 |
if not isinstance(properties, collections.OrderedDict):
|
|
184 |
keys = sorted(properties, key=lambda key: key.lower())
|
|
185 |
for key in keys:
|
|
186 |
sub = properties.get(key, {}).copy()
|
|
187 |
required = key in required_keys
|
|
188 |
# FIXME: workaround wrong schemas in vivaticket, gesbac,
|
|
189 |
# planitech, astregs, atal, iparapheur, iws, lille_kimoce
|
|
190 |
if sub.get('required') in (True, False):
|
|
191 |
required |= sub.pop('required')
|
|
192 |
sub_description = sub.pop('description', '')
|
|
193 |
sub_title = sub.pop('title', '')
|
|
194 |
s += format_html('<li><tt>{0}</tt>', key)
|
|
195 |
if required:
|
|
196 |
s += format_html('<span title="{}" class="required">*</span>', _('required'))
|
|
197 |
if description or sub:
|
|
198 |
s += ' :'
|
|
199 |
if sub_title:
|
|
200 |
s += format_html(' <em>{0}</em>', sub_title)
|
|
201 |
elif sub_description and '\n' not in sub_description:
|
|
202 |
s += format_html(' <em>{0}</em>', sub_description)
|
|
203 |
if sub_title or '\n' in sub_description:
|
|
204 |
s += format_html('\n<p class="description">{}</p>', sub_description)
|
|
205 |
if sub:
|
|
206 |
s += format_html('\n{0}', render_json_schema(sub))
|
|
207 |
s += '</li>'
|
|
208 |
s += '</ul>'
|
|
209 |
return mark_safe(s)
|
|
210 |
if typ == 'boolean':
|
|
211 |
if not schema:
|
|
212 |
return mark_safe('<b>bool</b>')
|
|
213 |
return format_html('<em>unknown {!r}</em>', original_schema)
|
|
214 |
|
|
215 |
|
|
216 |
@register.simple_tag(takes_context=False)
|
|
217 |
def render_body_schemas(body_schemas):
|
|
218 |
if not body_schemas:
|
|
219 |
return ''
|
|
220 |
|
|
221 |
s = mark_safe('<ul>')
|
|
222 |
for key in body_schemas:
|
|
223 |
if key == 'application/json':
|
|
224 |
s += mark_safe('<li><tt>application/json</tt> : <span class"json-schema">')
|
|
225 |
s += render_json_schema(body_schemas['application/json'])
|
|
226 |
s += mark_safe('</span></li>')
|
|
227 |
else:
|
|
228 |
s += format_html('<li><tt>{0}</tt></li>', key)
|
|
229 |
s += mark_safe('<ul>')
|
|
230 |
return mark_safe(s)
|
|
231 |
|