File size: 5,907 Bytes
2d876d1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
"""Module contains pre-built validators."""
import re
from pathlib import Path
from typing import Optional

from prompt_toolkit.validation import ValidationError, Validator

__all__ = [
    "PathValidator",
    "EmptyInputValidator",
    "PasswordValidator",
    "NumberValidator",
]


class NumberValidator(Validator):
    """:class:`~prompt_toolkit.validation.Validator` to validate if input is a number.

    Args:
        message: Error message to display in the validatation toolbar when validation failed.
        float_allowed: Allow input to contain floating number (with decimal).
    """

    def __init__(
        self, message: str = "Input should be a number", float_allowed: bool = False
    ) -> None:
        self._message = message
        self._float_allowed = float_allowed

    def validate(self, document) -> None:
        """Check if user input is a valid number.

        This method is used internally by `prompt_toolkit <https://python-prompt-toolkit.readthedocs.io/en/master/>`_.

        See Also:
            https://python-prompt-toolkit.readthedocs.io/en/master/pages/asking_for_input.html?highlight=validator#input-validation
        """
        try:
            if self._float_allowed:
                float(document.text)
            else:
                int(document.text)
        except ValueError:
            raise ValidationError(
                message=self._message, cursor_position=document.cursor_position
            )


class PathValidator(Validator):
    """:class:`~prompt_toolkit.validation.Validator` to validate if input is a valid filepath on the system.

    Args:
        message: Error message to display in the validatation toolbar when validation failed.
        is_file: Explicitly check if the input is a valid file on the system.
        is_dir: Explicitly check if the input is a valid directory/folder on the system.
    """

    def __init__(
        self,
        message: str = "Input is not a valid path",
        is_file: bool = False,
        is_dir: bool = False,
    ) -> None:
        self._message = message
        self._is_file = is_file
        self._is_dir = is_dir

    def validate(self, document) -> None:
        """Check if user input is a filepath that exists on the system based on conditions.

        This method is used internally by `prompt_toolkit <https://python-prompt-toolkit.readthedocs.io/en/master/>`_.

        See Also:
            https://python-prompt-toolkit.readthedocs.io/en/master/pages/asking_for_input.html?highlight=validator#input-validation
        """
        path = Path(document.text).expanduser()
        if self._is_file and not path.is_file():
            raise ValidationError(
                message=self._message,
                cursor_position=document.cursor_position,
            )
        elif self._is_dir and not path.is_dir():
            raise ValidationError(
                message=self._message,
                cursor_position=document.cursor_position,
            )
        elif not path.exists():
            raise ValidationError(
                message=self._message,
                cursor_position=document.cursor_position,
            )


class EmptyInputValidator(Validator):
    """:class:`~prompt_toolkit.validation.Validator` to validate if the input is empty.

    Args:
        message: Error message to display in the validatation toolbar when validation failed.
    """

    def __init__(self, message: str = "Input cannot be empty") -> None:
        self._message = message

    def validate(self, document) -> None:
        """Check if user input is empty.

        This method is used internally by `prompt_toolkit <https://python-prompt-toolkit.readthedocs.io/en/master/>`_.

        See Also:
            https://python-prompt-toolkit.readthedocs.io/en/master/pages/asking_for_input.html?highlight=validator#input-validation
        """
        if not len(document.text) > 0:
            raise ValidationError(
                message=self._message,
                cursor_position=document.cursor_position,
            )


class PasswordValidator(Validator):
    """:class:`~prompt_toolkit.validation.Validator` to validate password compliance.

    Args:
        message: Error message to display in the validatation toolbar when validation failed.
        length: The minimum length of the password.
        cap: Password should include at least one capital letter.
        special: Password should include at least one special char "@$!%*#?&".
        number: Password should include at least one number.
    """

    def __init__(
        self,
        message: str = "Input is not compliant with the password constraints",
        length: Optional[int] = None,
        cap: bool = False,
        special: bool = False,
        number: bool = False,
    ) -> None:
        password_pattern = r"^"
        if cap:
            password_pattern += r"(?=.*[A-Z])"
        if special:
            password_pattern += r"(?=.*[@$!%*#?&])"
        if number:
            password_pattern += r"(?=.*[0-9])"
        password_pattern += r"."
        if length:
            password_pattern += r"{%s,}" % length
        else:
            password_pattern += r"*"
        password_pattern += r"$"
        self._re = re.compile(password_pattern)
        self._message = message

    def validate(self, document) -> None:
        """Check if user input is compliant with the specified password constraints.

        This method is used internally by `prompt_toolkit <https://python-prompt-toolkit.readthedocs.io/en/master/>`_.

        See Also:
            https://python-prompt-toolkit.readthedocs.io/en/master/pages/asking_for_input.html?highlight=validator#input-validation
        """
        if not self._re.match(document.text):
            raise ValidationError(
                message=self._message, cursor_position=document.cursor_position
            )