schemavalidator.py 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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')
  13. def validate_geojson(d):
  14. """
  15. Make sure a geojson dict only contains allowed geometry types
  16. """
  17. type_=d.get('type')
  18. if type_ not in geojson_allowed_types:
  19. return False
  20. return True
  21. def validate_isp(jdict):
  22. """
  23. Validate a json-object against the isp json-schema
  24. """
  25. if not 'version' in jdict:
  26. raise ValidationError(u'version is a required property')
  27. try:
  28. schema=_schema.versions.get(jdict['version'])
  29. except (AttributeError, TypeError):
  30. raise ValidationError(u'version %r unsupported'%jdict['version'])
  31. v=Draft4Validator(
  32. schema,
  33. resolver=MyRefResolver.from_schema(schema, store=_schema.deps_for_version(jdict['version'])),
  34. format_checker=draft4_format_checker,
  35. )
  36. for err in v.iter_errors(jdict):
  37. yield err
  38. def is_valid_url(u):
  39. try:
  40. pu=urlsplit(u)
  41. except:
  42. return False
  43. if pu.scheme not in ('', 'http', 'https'):
  44. return False
  45. if not pu.netloc:
  46. return False
  47. return True
  48. if 'website' in jdict and not is_valid_url(jdict['website']):
  49. yield ValidationError(u'%r must be an absolute HTTP URL'%u'website',
  50. instance=jdict[u'website'], schema=schema[u'properties'][u'website'],
  51. path=[u'website'], schema_path=[u'properties', u'website', u'description'],
  52. validator=u'validate_url', validator_value=jdict['website'])
  53. if 'logoURL' in jdict and not is_valid_url(jdict['logoURL']):
  54. yield ValidationError(u'%r must be an absolute HTTP URL'%u'logoURL',
  55. instance=jdict[u'logoURL'], schema=schema[u'properties'][u'logoURL'],
  56. path=[u'logoURL'], schema_path=[u'properties', u'logoURL', u'description'],
  57. validator=u'validate_url', validator_value=jdict['logoURL'])
  58. sch=schema[u'properties'][u'otherWebsites'][u'patternProperties'][u'^.+$']
  59. for name, url in jdict.get('otherWebsites', {}).iteritems():
  60. if is_valid_url(url):
  61. continue
  62. yield ValidationError(u'%r must be an absolute HTTP URL'%name,
  63. instance=url, schema=sch, path=[u'otherWebsite', name],
  64. schema_path=[u'properties', u'otherWebsites', u'patternProperties', u'^.+$', 'description'],
  65. validator=u'validate_url', validator_value=url)
  66. for i, ca in enumerate(jdict.get('coveredAreas', [])):
  67. area=ca.get('area')
  68. if area and validate_geojson(area):
  69. continue
  70. elif not area:
  71. continue
  72. yield ValidationError(
  73. u'GeoJSON can only contain the following types: %s'%repr(geojson_allowed_types),
  74. instance=ca, schema=schema[u'definitions'][u'coveredArea'][u'properties'][u'area'],
  75. path=['coveredAreas', i, 'area'],
  76. schema_path=[u'properties', u'coveredAreas', u'items', u'properties', u'area'],
  77. validator=u'validate_geojson', validator_value=ca
  78. )