schemavalidator.py 3.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. # -*- coding: utf-8 -*-
  2. import ispformat.schema as _schema
  3. from jsonschema import Draft4Validator, RefResolver, draft4_format_checker
  4. from jsonschema.exceptions import RefResolutionError, SchemaError, ValidationError
  5. import json
  6. import os.path
  7. from urlparse import urlsplit
  8. class MyRefResolver(RefResolver):
  9. def resolve_remote(self, uri):
  10. # Prevent remote resolving
  11. raise RefResolutionError("LOL NOPE")
  12. geojson_allowed_types=('Polygon', 'MultiPolygon', 'GeometryCollection')
  13. def validate_geojson(_d):
  14. """
  15. Make sure a geojson dict only contains allowed geometry types
  16. """
  17. def inner(d):
  18. type_=d.get('type')
  19. if type_ not in geojson_allowed_types:
  20. return False
  21. if type_ == 'GeometryCollection':
  22. for d2 in d['geometries']:
  23. if not inner(d2):
  24. return False
  25. return True
  26. return inner(_d)
  27. def validate_isp(jdict):
  28. """
  29. Validate a json-object against the isp json-schema
  30. """
  31. if not 'version' in jdict:
  32. raise ValidationError(u'version is a required property')
  33. try:
  34. schema=_schema.versions.get(jdict['version'])
  35. except (AttributeError, TypeError):
  36. raise ValidationError(u'version %r unsupported'%jdict['version'])
  37. v=Draft4Validator(
  38. schema,
  39. resolver=MyRefResolver.from_schema(schema, store=_schema.deps_for_version(jdict['version'])),
  40. format_checker=draft4_format_checker,
  41. )
  42. for err in v.iter_errors(jdict):
  43. yield err
  44. def is_valid_url(u):
  45. try:
  46. pu=urlsplit(u)
  47. except:
  48. return False
  49. if pu.scheme not in ('', 'http', 'https'):
  50. return False
  51. if not pu.netloc:
  52. return False
  53. return True
  54. if 'website' in jdict and not is_valid_url(jdict['website']):
  55. yield ValidationError(u'%r must be an absolute HTTP URL'%u'website',
  56. instance=jdict[u'website'], schema=schema[u'properties'][u'website'],
  57. path=[u'website'], schema_path=[u'properties', u'website', u'description'],
  58. validator=u'validate_url', validator_value=jdict['website'])
  59. if 'logoURL' in jdict and not is_valid_url(jdict['logoURL']):
  60. yield ValidationError(u'%r must be an absolute HTTP URL'%u'logoURL',
  61. instance=jdict[u'logoURL'], schema=schema[u'properties'][u'logoURL'],
  62. path=[u'logoURL'], schema_path=[u'properties', u'logoURL', u'description'],
  63. validator=u'validate_url', validator_value=jdict['logoURL'])
  64. sch=schema[u'properties'][u'otherWebsites'][u'patternProperties'][u'^.+$']
  65. for name, url in jdict.get('otherWebsites', {}).iteritems():
  66. if is_valid_url(url):
  67. continue
  68. yield ValidationError(u'%r must be an absolute HTTP URL'%name,
  69. instance=url, schema=sch, path=[u'otherWebsite', name],
  70. schema_path=[u'properties', u'otherWebsites', u'patternProperties', u'^.+$', 'description'],
  71. validator=u'validate_url', validator_value=url)
  72. for i, ca in enumerate(jdict.get('coveredAreas', [])):
  73. if validate_geojson(ca.get('area', {})):
  74. continue
  75. yield ValidationError(
  76. u'GeoJSON can only contain the following types: %s'%repr(geojson_allowed_types),
  77. instance=ca, schema=schema[u'definitions'][u'coveredArea'][u'properties'][u'area'],
  78. path=['coveredAreas', i, 'area'],
  79. schema_path=[u'properties', u'coveredAreas', u'items', u'properties', u'area'],
  80. validator=u'validate_geojson', validator_value=ca
  81. )