]> git.llucax.com Git - software/pymin.git/blob - pymin/validation.py
Add GPL v3 license to the project
[software/pymin.git] / pymin / validation.py
1 # vim: set encoding=utf-8 et sw=4 sts=4 :
2
3 import re
4 from formencode import Invalid
5 from formencode.validators import *
6 from formencode.compound import *
7
8 from pymin.item import Item
9 from pymin.validatedclass import Field
10
11
12 class Int8(Int):
13     min = -128
14     max = +127
15
16 class UInt8(Int):
17     min = 0
18     max = 255
19
20 class Int16(Int):
21     min = -32768
22     max = +32767
23
24 class UInt16(Int):
25     min = 0
26     max = 65535
27
28 class Int32(Int):
29     min = -2147483648
30     max = +2147483647
31
32 class UInt32(Int):
33     min = 0
34     max = 4294967295
35
36 class Int64(Int):
37     min = -9223372036854775808
38     max = +9223372036854775807
39
40 class UInt64(Int):
41     min = 0
42     max = 18446744073709551615
43
44
45 class UpOneOf(OneOf):
46     """
47     Same as :class:`OneOf` but values are uppercased before validation.
48
49     Examples::
50
51         >>> uoo = UpOneOf(['A', 'B', 'C'])
52         >>> uoo.to_python('a')
53         'A'
54         >>> uoo.to_python('B')
55         'B'
56         >>> uoo.to_python('x')
57         Traceback (most recent call last):
58             ...
59         Invalid: Value must be one of: A; B; C (not 'X')
60     """
61
62     def _to_python(self, value, state):
63         return value.upper()
64
65
66 class HostName(FancyValidator):
67     """
68     Formencode validator to check whether a string is a correct host name
69
70     Examples::
71
72         >>> n = HostName()
73         >>> n.to_python('host-name')
74         'hostname'
75         >>> n.to_python('host name')
76         Traceback (most recent call last):
77             ...
78         Invalid: Not a valid host name
79         >>> n.to_python('hostname' * 8)
80         Traceback (most recent call last):
81             ...
82         Invalid: Host name is too long (maximum length is 63 characters)
83     """
84
85     messages = dict(
86         empty = u'Please enter a host name',
87         bad_format = u'Not a valid host name',
88         too_long = u'Host name is too long (maximum length is '
89                          u'%(max_len)d characters)',
90     )
91
92     max_len = 63 # official limit for a label
93     hostnameRE = re.compile(r"^[a-zA-Z0-9][\w\-]*$")
94
95     def validate_python(self, value, state):
96         if len(value) > self.max_len:
97             raise Invalid(self.message('host_too_long', state, value=value,
98                                        max_len=self.max_len),
99                           value, state)
100         if not self.hostnameRE.search(value):
101             raise Invalid(self.message('bad_format', state, value=value),
102                           value, state)
103
104
105 class FullyQualifiedHostName(HostName):
106     """
107     Formencode validator to check whether a string is a correct host name
108
109     Examples::
110
111         >>> n = FullyQualifiedHostName()
112         >>> n.to_python('example.com')
113         'example.com'
114         >>> n.to_python('example')
115         Traceback (most recent call last):
116             ...
117         Invalid: Not a valid host name
118         >>> n.to_python('example.' * 32 + 'com')
119         Traceback (most recent call last):
120             ...
121         Invalid: Host name is too long (maximum length is 253 characters)
122     """
123
124     messages = dict(HostName._messages,
125         empty = u'Please enter a fully qualified host name',
126         bad_format = u'Not a fully qualified host name',
127     )
128
129     max_len = 253
130     hostnameRE = re.compile(r"^[a-zA-Z0-9][\w\-\.]*\.[a-zA-Z]+$")
131
132
133 class IPAddress(FancyValidator):
134     """
135     Formencode validator to check whether a string is a correct IP address
136
137     Examples::
138
139         >>> ip = IPAddress()
140         >>> ip.to_python('127.0.0.1')
141         '127.0.0.1'
142         >>> ip.to_python('299.0.0.1')
143         Traceback (most recent call last):
144             ...
145         Invalid: The octets must be within the range of 0-255 (not '299')
146         >>> ip.to_python('192.168.0.1/1')
147         Traceback (most recent call last):
148             ...
149         Invalid: Please enter a valid IP address (a.b.c.d)
150         >>> ip.to_python('asdf')
151         Traceback (most recent call last):
152             ...
153         Invalid: Please enter a valid IP address (a.b.c.d)
154     """
155     messages = {
156         'bad_format' : u'Please enter a valid IP address (a.b.c.d)',
157         'illegal_octets' : u'The octets must be within the range of 0-255 (not %(octet)r)',
158     }
159
160     def validate_python(self, value, state):
161         try:
162             octets = value.split('.')
163
164             # Only 4 octets?
165             if len(octets) != 4:
166                 raise Invalid(self.message("bad_format", state, value=value), value, state)
167
168             # Correct octets?
169             for octet in octets:
170                 if int(octet) < 0 or int(octet) > 255:
171                     raise Invalid(self.message("illegal_octets", state, octet=octet), value, state)
172
173         # Splitting faild: wrong syntax
174         except ValueError:
175             raise Invalid(self.message("bad_format", state), value, state)
176
177