schemavalidator.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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 urlparse
  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_diyisp(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=urlparse(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)
  78. if __name__ == '__main__':
  79. import sys
  80. j=json.load(open(sys.argv[1]))
  81. for e in validate_diyisp(j):
  82. print e