schemavalidator.py 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. # -*- coding: utf-8 -*-
  2. from jsonschema import Draft4Validator, RefResolver, draft4_format_checker
  3. from jsonschema.exceptions import RefResolutionError, SchemaError, ValidationError
  4. import json
  5. import os.path
  6. from urlparse import urlsplit
  7. class MyRefResolver(RefResolver):
  8. def resolve_remote(self, uri):
  9. # Prevent remote resolving
  10. raise RefResolutionError("LOL NOPE")
  11. def load_schema(name):
  12. """
  13. Load a schema from ./schemas/``name``.json and return it.
  14. """
  15. schemadir = os.path.join(
  16. os.path.dirname(os.path.abspath(__file__)),
  17. 'schemas'
  18. )
  19. schemapath = os.path.join(schemadir, '%s.json' % (name,))
  20. with open(schemapath) as f:
  21. return json.load(f)
  22. schemas={
  23. 0.1: load_schema('isp-0.1')
  24. }
  25. resources={
  26. 'http://json-schema.org/geo': load_schema('geo'),
  27. 'http://json-schema.org/address': load_schema('address'),
  28. 'http://json-schema.org/geojson/geojson.json#': load_schema('geojson/geojson'),
  29. 'http://json-schema.org/geojson/geometry.json#': load_schema('geojson/geometry'),
  30. 'http://json-schema.org/geojson/bbox.json#': load_schema('geojson/bbox'),
  31. 'http://json-schema.org/geojson/crs.json#': load_schema('geojson/crs'),
  32. }
  33. def validate_isp(jdict):
  34. """
  35. Validate a json-object against the diyisp json-schema
  36. """
  37. if not 'version' in jdict:
  38. raise ValidationError(u'version is a required property')
  39. try:
  40. schema=schemas.get(jdict['version'])
  41. except (AttributeError, TypeError):
  42. raise ValidationError(u'version %r unsupported'%jdict['version'])
  43. v=Draft4Validator(
  44. schema,
  45. resolver=MyRefResolver.from_schema(schema, store=resources),
  46. format_checker=draft4_format_checker,
  47. )
  48. for err in v.iter_errors(jdict):
  49. yield err
  50. def is_valid_url(u):
  51. try:
  52. pu=urlsplit(u)
  53. except:
  54. return False
  55. if pu.scheme not in ('', 'http', 'https'):
  56. return False
  57. if not pu.netloc:
  58. return False
  59. return True
  60. if 'website' in jdict and not is_valid_url(jdict['website']):
  61. yield ValidationError(u'%r must be an absolute HTTP URL'%u'website',
  62. instance=jdict[u'website'], schema=schema[u'properties'][u'website'],
  63. path=[u'website'], schema_path=[u'properties', u'website', u'description'],
  64. validator=u'validate_url', validator_value=jdict['website'])
  65. if 'logoURL' in jdict and not is_valid_url(jdict['logoURL']):
  66. yield ValidationError(u'%r must be an absolute HTTP URL'%u'logoURL',
  67. instance=jdict[u'logoURL'], schema=schema[u'properties'][u'logoURL'],
  68. path=[u'logoURL'], schema_path=[u'properties', u'logoURL', u'description'],
  69. validator=u'validate_url', validator_value=jdict['logoURL'])
  70. sch=schema[u'properties'][u'otherWebsites'][u'patternProperties'][u'^.+$']
  71. for name, url in jdict.get('otherWebsites', {}).iteritems():
  72. if is_valid_url(url):
  73. continue
  74. yield ValidationError(u'%r must be an absolute HTTP URL'%name,
  75. instance=url, schema=sch, path=[u'otherWebsite', name],
  76. schema_path=[u'properties', u'otherWebsites', u'patternProperties', u'^.+$', 'description'],
  77. validator=u'validate_url', validator_value=url)