#!/usr/bin/env python3 # Copyright 2018 vg@devys.org # SPDX-License-Identifier: MIT import collections import datetime import os import pprint import sys import jsonschema import yaml def convert_types(obj): if isinstance(obj, str): return obj elif isinstance(obj, datetime.date): return obj.strftime('%F') elif isinstance(obj, collections.Sequence): for i, _ in enumerate(obj): obj[i] = convert_types(obj[i]) elif isinstance(obj, collections.Mapping): for k, v in obj.items(): obj[k] = convert_types(v) return obj def print_contact(contact): cfield = '\033[31;1m' cnormal = '\033[0m' print(f'{cfield}Contact{cnormal}: {contact["display"]}' f' [{cfield}uuid{cnormal}: {contact["uuid"]}]') def print_validation_error(data_obj, exception): print('Best match error:') print(exception) print() cfield = '\033[31;1m' cnormal = '\033[0m' print('Errors in context sorted by relevance:') for i, suberror in enumerate(sorted(exception.context, key=jsonschema.exceptions.relevance)): if i: print() print(f'=> {cfield}schema{cnormal}:', '.'.join(str(e) for e in suberror.absolute_schema_path)) print(f' {cfield}instance{cnormal}:', '.'.join(str(e) for e in suberror.absolute_path)) print(f' {cfield}E{cnormal}:', suberror.message) print(f'Error occured on: {".".join(str(i) for i in exception.absolute_path)}') print_contact(data_obj[exception.path[0]]) print() def validate_yaml_data(data_obj, schema_obj): try: jsonschema.validate(convert_types(data_obj), schema_obj) except jsonschema.ValidationError as e: print_validation_error(data_obj, e) # schema ok, check for duplicates in display and uuids display_dups = collections.defaultdict(list) uuid_dups = collections.defaultdict(list) for index, item in enumerate(data_obj): display_dups[item['display']].append(index) uuid_dups[item['uuid']].append(index) for e in (data_obj[e] for e in display_dups.values() if len(e) > 2): print('WARNING: duplicated display value for these contacts:') print(f'=> display: {e["display"]} uuid: {e["uuid"]}') for e in (data_obj[e] for e in uuid_dups.values() if len(e) > 2): print('ERROR: duplicated uuid value for these contacts:') print(f'=> display: {e["display"]} uuid: {e["uuid"]}')