summaryrefslogtreecommitdiffstats
path: root/contacts_validation/contacts_validation/__init__.py
blob: c9c75bef5353980af19f4014a2d1ea20f1b6ae61 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!/usr/bin/env python3
# Copyright 2023 vg@devys.org
# SPDX-License-Identifier: MIT

import collections
import datetime
import os
import pprint
import sys
import typing

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, typing.Sequence):
        for i, _ in enumerate(obj):
            obj[i] = convert_types(obj[i])
    elif isinstance(obj, typing.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):
    valid = True
    try:
        jsonschema.validate(convert_types(data_obj), schema_obj)
    except jsonschema.ValidationError as e:
        print_validation_error(data_obj, e)
        valid = False

    # 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"]}')
        valid = False # by default warning are errors on cmdline
    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"]}')
        valid = False

    return valid