phone_number_value.py 1.73 KB
Newer Older
Pierre Dittgen's avatar
Pierre Dittgen committed
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
import phonenumbers
from frictionless import Check, errors


class PhoneNumberValueError(errors.CellError):
    """Custom error."""

    code = "phone-number-value"
    name = "Numéro de téléphone invalide"
    tags = ["#body"]
    template = "La valeur '{cell}' n'est pas un numéro de téléphone valide."
    description = (
        "Les numéros de téléphone acceptés sont les numéros français à 10 chiffres"
        " (ex : `01 99 00 27 37`) ou au format international avec le préfixe du pays"
        " (ex : `+33 1 99 00 27 37`). Les numéros courts (`115` par exemple) sont"
        " également acceptés."
    )


class PhoneNumberValue(Check):
    """Check phone number validity."""

    possible_Errors = [PhoneNumberValueError]  # type: ignore

    def __init__(self, descriptor=None):
        super().__init__(descriptor)
        self.__column = self.get("column")

    def validate_start(self):
        if self.__column not in self.resource.schema.field_names:
            note = f"La colonne {self.__column!r} est manquante."
            yield errors.TaskError(note=note)

    def validate_row(self, row):
        cell_value = row[self.__column]

        # Empty cell, don't check!
        if not cell_value:
            return

        try:
            phonenumbers.parse(cell_value, "FR")
        except phonenumbers.NumberParseException:
            try:
                phonenumbers.parse(cell_value)
            except phonenumbers.NumberParseException:
                yield PhoneNumberValueError.from_row(
                    row, note="", field_name=self.__column
                )

    metadata_profile = {  # type: ignore
        "type": "object",
        "required": ["column"],
        "properties": {"column": {"type": "string"}},
    }