Merge pull request #411 from niphlod/docs/te-x
sphinx-compatible docstring (only DAL remains)
This commit is contained in:
commit
0c1fa92705
6 files changed
+575
-504
No files matched your search
+293
-289
File diff suppressed because it is too large.
Load diff
+27
-30
@@ -1,15 +1,14 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
This file is part of the web2py Web Framework
|
| This file is part of the web2py Web Framework
|
||||||
Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
|
| Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
|
||||||
License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
|
| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
|
||||||
|
| Created by Vladyslav Kozlovskyy (Ukraine) <dbdevelop©gmail.com>
|
||||||
Created by Vladyslav Kozlovskyy (Ukraine) <dbdevelop©gmail.com>
|
| for Web2py project
|
||||||
for Web2py project
|
|
||||||
|
|
||||||
Utilities and class for UTF8 strings managing
|
Utilities and class for UTF8 strings managing
|
||||||
===========================================
|
----------------------------------------------
|
||||||
"""
|
"""
|
||||||
import __builtin__
|
import __builtin__
|
||||||
__all__ = ['Utf8']
|
__all__ = ['Utf8']
|
||||||
@@ -34,7 +33,8 @@ def sort_key(s):
|
|||||||
is used for utf-8 and unicode strings sorting and for utf-8 strings
|
is used for utf-8 and unicode strings sorting and for utf-8 strings
|
||||||
comparison
|
comparison
|
||||||
|
|
||||||
NOTE: pyuca is a very memory cost module! It loads the whole
|
Note:
|
||||||
|
pyuca is a very memory cost module! It loads the whole
|
||||||
"allkey.txt" file (~2mb!) into the memory. But this
|
"allkey.txt" file (~2mb!) into the memory. But this
|
||||||
functionality is needed only when sort_key() is called as a
|
functionality is needed only when sort_key() is called as a
|
||||||
part of sort() function or when Utf8 strings are compared.
|
part of sort() function or when Utf8 strings are compared.
|
||||||
@@ -56,8 +56,7 @@ def sort_key(s):
|
|||||||
|
|
||||||
|
|
||||||
def ord(char):
|
def ord(char):
|
||||||
""" returns unicode id for utf8 or unicode *char* character
|
"""Returns unicode id for utf8 or unicode *char* character
|
||||||
|
|
||||||
SUPPOSE that *char* is an utf-8 or unicode character only
|
SUPPOSE that *char* is an utf-8 or unicode character only
|
||||||
"""
|
"""
|
||||||
if isinstance(char, unicode):
|
if isinstance(char, unicode):
|
||||||
@@ -66,27 +65,28 @@ def ord(char):
|
|||||||
|
|
||||||
|
|
||||||
def chr(code):
|
def chr(code):
|
||||||
""" return utf8-character with *code* unicode id """
|
"""Returns utf8-character with *code* unicode id """
|
||||||
return Utf8(unichr(code))
|
return Utf8(unichr(code))
|
||||||
|
|
||||||
|
|
||||||
def size(string):
|
def size(string):
|
||||||
""" return length of utf-8 string in bytes
|
"""Returns length of utf-8 string in bytes
|
||||||
NOTE! The length of correspondent utf-8
|
|
||||||
string is returned for unicode string
|
Note:
|
||||||
|
The length of correspondent utf-8 string is returned for unicode string
|
||||||
"""
|
"""
|
||||||
return Utf8(string).__size__()
|
return Utf8(string).__size__()
|
||||||
|
|
||||||
|
|
||||||
def truncate(string, length, dots='...'):
|
def truncate(string, length, dots='...'):
|
||||||
""" returns string of length < *length* or truncate
|
"""Returns string of length < *length* or truncate string with adding
|
||||||
string with adding *dots* suffix to the string's end
|
*dots* suffix to the string's end
|
||||||
|
|
||||||
args:
|
Args:
|
||||||
length (int): max length of string
|
length (int): max length of string
|
||||||
dots (str or unicode): string suffix, when string is cutted
|
dots (str or unicode): string suffix, when string is cutted
|
||||||
|
|
||||||
returns:
|
Returns:
|
||||||
(utf8-str): original or cutted string
|
(utf8-str): original or cutted string
|
||||||
"""
|
"""
|
||||||
text = unicode(string, 'utf-8')
|
text = unicode(string, 'utf-8')
|
||||||
@@ -125,7 +125,7 @@ class Utf8(str):
|
|||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
r''' # note that we use raw strings to avoid having to use double back slashes below
|
r''' # note that we use raw strings to avoid having to use double back slashes below
|
||||||
NOTE! This function is a clone of web2py:gluon.languages.utf_repl() function
|
NOTE! This function is a clone of web2py:gluon.languages.utf_repl() function::
|
||||||
|
|
||||||
utf8.__repr__() works same as str.repr() when processing ascii string
|
utf8.__repr__() works same as str.repr() when processing ascii string
|
||||||
>>> repr(Utf8('abc')) == repr(Utf8("abc")) == repr('abc') == repr("abc") == "'abc'"
|
>>> repr(Utf8('abc')) == repr(Utf8("abc")) == repr('abc') == repr("abc") == "'abc'"
|
||||||
@@ -139,7 +139,8 @@ class Utf8(str):
|
|||||||
>>> repr(Utf8('a\r\nb')) == repr('a\r\nb') == "'a\\r\\nb'" # Test for \r, \n
|
>>> repr(Utf8('a\r\nb')) == repr('a\r\nb') == "'a\\r\\nb'" # Test for \r, \n
|
||||||
True
|
True
|
||||||
|
|
||||||
Unlike str.repr(), Utf8.__repr__() remains utf8 content when processing utf8 string
|
Unlike str.repr(), Utf8.__repr__() remains utf8 content when processing utf8 string::
|
||||||
|
|
||||||
>>> repr(Utf8('中文字')) == repr(Utf8("中文字")) == "'中文字'" != repr('中文字')
|
>>> repr(Utf8('中文字')) == repr(Utf8("中文字")) == "'中文字'" != repr('中文字')
|
||||||
True
|
True
|
||||||
>>> repr(Utf8('中"文"字')) == "'中\"文\"字'" != repr('中"文"字')
|
>>> repr(Utf8('中"文"字')) == "'中\"文\"字'" != repr('中"文"字')
|
||||||
@@ -578,11 +579,9 @@ if __name__ == '__main__':
|
|||||||
7
|
7
|
||||||
>>> a=Utf8('а б ц д е а б ц д е а\\tб ц д е')
|
>>> a=Utf8('а б ц д е а б ц д е а\\tб ц д е')
|
||||||
>>> a.split()
|
>>> a.split()
|
||||||
['а', 'б', 'ц', 'д', 'е', 'а', 'б', 'ц', 'д',
|
['а', 'б', 'ц', 'д', 'е', 'а', 'б', 'ц', 'д', 'е', 'а', 'б', 'ц', 'д', 'е']
|
||||||
'е', 'а', 'б', 'ц', 'д', 'е']
|
|
||||||
>>> a.rsplit()
|
>>> a.rsplit()
|
||||||
['а', 'б', 'ц', 'д', 'е', 'а', 'б', 'ц', 'д',
|
['а', 'б', 'ц', 'д', 'е', 'а', 'б', 'ц', 'д', 'е', 'а', 'б', 'ц', 'д', 'е']
|
||||||
'е', 'а', 'б', 'ц', 'д', 'е']
|
|
||||||
>>> a.expandtabs().split('б')
|
>>> a.expandtabs().split('б')
|
||||||
['а ', ' ц д е а ', ' ц д е а ', ' ц д е']
|
['а ', ' ц д е а ', ' ц д е а ', ' ц д е']
|
||||||
>>> a.expandtabs().rsplit('б')
|
>>> a.expandtabs().rsplit('б')
|
||||||
@@ -630,8 +629,7 @@ if __name__ == '__main__':
|
|||||||
1
|
1
|
||||||
>>> s.count('Є', 0, 5)
|
>>> s.count('Є', 0, 5)
|
||||||
0
|
0
|
||||||
>>> Utf8(
|
>>> Utf8("Parameters: '%(проба)s', %(probe)04d, %(проба2)s") % { u"проба": s,
|
||||||
"Parameters: '%(проба)s', %(probe)04d, %(проба2)s") % { u"проба": s,
|
|
||||||
... "not used": "???", "probe": 2, "проба2": u"ПРоба Probe" }
|
... "not used": "???", "probe": 2, "проба2": u"ПРоба Probe" }
|
||||||
"Parameters: 'ПРоба Є PRobe', 0002, ПРоба Probe"
|
"Parameters: 'ПРоба Є PRobe', 0002, ПРоба Probe"
|
||||||
>>> a=Utf8(u"Параметр: (%s)-(%s)-[%s]")
|
>>> a=Utf8(u"Параметр: (%s)-(%s)-[%s]")
|
||||||
@@ -694,8 +692,7 @@ if __name__ == '__main__':
|
|||||||
аАбБвВгГґҐдДеЕєЄжЖзЗиИіІїЇйЙкКлЛмМнНоОпПрРсСтТуУфФхХцЦчЧшШщЩьЬюЮяЯ
|
аАбБвВгГґҐдДеЕєЄжЖзЗиИіІїЇйЙкКлЛмМнНоОпПрРсСтТуУфФхХцЦчЧшШщЩьЬюЮяЯ
|
||||||
>>> Utf8().join(sorted(c.decode(), key=sort_key)) # convert to unicode for better performance
|
>>> Utf8().join(sorted(c.decode(), key=sort_key)) # convert to unicode for better performance
|
||||||
'аАбБвВгГґҐдДеЕєЄжЖзЗиИіІїЇйЙкКлЛмМнНоОпПрРсСтТуУфФхХцЦчЧшШщЩьЬюЮяЯ'
|
'аАбБвВгГґҐдДеЕєЄжЖзЗиИіІїЇйЙкКлЛмМнНоОпПрРсСтТуУфФхХцЦчЧшШщЩьЬюЮяЯ'
|
||||||
>>> for result in sorted(
|
>>> for result in sorted(["Іа", "Астро", u"гала", Utf8("Гоша"), "Єва", "шовк", "аякс", "Їжа",
|
||||||
["Іа", "Астро", u"гала", Utf8("Гоша"), "Єва", "шовк", "аякс", "Їжа",
|
|
||||||
... "ґанок", Utf8("Дар'я"), "білінг", "веб", u"Жужа", "проба", u"тест",
|
... "ґанок", Utf8("Дар'я"), "білінг", "веб", u"Жужа", "проба", u"тест",
|
||||||
... "абетка", "яблуко", "Юляся", "Київ", "лимонад", "ложка", "Матриця",
|
... "абетка", "яблуко", "Юляся", "Київ", "лимонад", "ложка", "Матриця",
|
||||||
... ], key=sort_key):
|
... ], key=sort_key):
|
||||||
@@ -722,6 +719,7 @@ if __name__ == '__main__':
|
|||||||
шовк <type 'str'>
|
шовк <type 'str'>
|
||||||
Юляся <type 'str'>
|
Юляся <type 'str'>
|
||||||
яблуко <type 'str'>
|
яблуко <type 'str'>
|
||||||
|
|
||||||
>>> a=Utf8("中文字")
|
>>> a=Utf8("中文字")
|
||||||
>>> L=list(a)
|
>>> L=list(a)
|
||||||
>>> L
|
>>> L
|
||||||
@@ -734,8 +732,7 @@ if __name__ == '__main__':
|
|||||||
>>> a="中文字" # standard str type
|
>>> a="中文字" # standard str type
|
||||||
>>> L=list(a)
|
>>> L=list(a)
|
||||||
>>> L
|
>>> L
|
||||||
['\\xe4', '\\xb8', '\\xad', '\\xe6', '\\x96', '\\x87',
|
['\\xe4', '\\xb8', '\\xad', '\\xe6', '\\x96', '\\x87', '\\xe5', '\\xad', '\\x97']
|
||||||
'\\xe5', '\\xad', '\\x97']
|
|
||||||
>>> from string import maketrans
|
>>> from string import maketrans
|
||||||
>>> str_tab=maketrans('PRobe','12345')
|
>>> str_tab=maketrans('PRobe','12345')
|
||||||
>>> unicode_tab={ord(u'П'):ord(u'Ж'),
|
>>> unicode_tab={ord(u'П'):ord(u'Ж'),
|
||||||
|
|||||||
+12
-8
@@ -2,11 +2,12 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This file is part of the web2py Web Framework
|
| This file is part of the web2py Web Framework
|
||||||
Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
|
| Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
|
||||||
License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
|
| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
|
||||||
|
|
||||||
This file specifically includes utilities for security.
|
This file specifically includes utilities for security.
|
||||||
|
--------------------------------------------------------
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import threading
|
import threading
|
||||||
@@ -65,7 +66,7 @@ def AES_new(key, IV=None):
|
|||||||
|
|
||||||
|
|
||||||
def compare(a, b):
|
def compare(a, b):
|
||||||
""" compares two strings and not vulnerable to timing attacks """
|
""" Compares two strings and not vulnerable to timing attacks """
|
||||||
if len(a) != len(b):
|
if len(a) != len(b):
|
||||||
return False
|
return False
|
||||||
result = 0
|
result = 0
|
||||||
@@ -75,7 +76,7 @@ def compare(a, b):
|
|||||||
|
|
||||||
|
|
||||||
def md5_hash(text):
|
def md5_hash(text):
|
||||||
""" Generate a md5 hash with the given text """
|
""" Generates a md5 hash with the given text """
|
||||||
return md5(text).hexdigest()
|
return md5(text).hexdigest()
|
||||||
|
|
||||||
def simple_hash(text, key='', salt='', digest_alg='md5'):
|
def simple_hash(text, key='', salt='', digest_alg='md5'):
|
||||||
@@ -177,7 +178,7 @@ def secure_loads(data, encryption_key, hash_key=None, compression_level=None):
|
|||||||
def initialize_urandom():
|
def initialize_urandom():
|
||||||
"""
|
"""
|
||||||
This function and the web2py_uuid follow from the following discussion:
|
This function and the web2py_uuid follow from the following discussion:
|
||||||
http://groups.google.com/group/web2py-developers/browse_thread/thread/7fd5789a7da3f09
|
`http://groups.google.com/group/web2py-developers/browse_thread/thread/7fd5789a7da3f09`
|
||||||
|
|
||||||
At startup web2py compute a unique ID that identifies the machine by adding
|
At startup web2py compute a unique ID that identifies the machine by adding
|
||||||
uuid.getnode() + int(time.time() * 1e3)
|
uuid.getnode() + int(time.time() * 1e3)
|
||||||
@@ -225,7 +226,7 @@ UNPACKED_CTOKENS, HAVE_URANDOM = initialize_urandom()
|
|||||||
|
|
||||||
def fast_urandom16(urandom=[], locker=threading.RLock()):
|
def fast_urandom16(urandom=[], locker=threading.RLock()):
|
||||||
"""
|
"""
|
||||||
this is 4x faster than calling os.urandom(16) and prevents
|
This is 4x faster than calling os.urandom(16) and prevents
|
||||||
the "too many files open" issue with concurrent access to os.urandom()
|
the "too many files open" issue with concurrent access to os.urandom()
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
@@ -243,7 +244,7 @@ def fast_urandom16(urandom=[], locker=threading.RLock()):
|
|||||||
def web2py_uuid(ctokens=UNPACKED_CTOKENS):
|
def web2py_uuid(ctokens=UNPACKED_CTOKENS):
|
||||||
"""
|
"""
|
||||||
This function follows from the following discussion:
|
This function follows from the following discussion:
|
||||||
http://groups.google.com/group/web2py-developers/browse_thread/thread/7fd5789a7da3f09
|
`http://groups.google.com/group/web2py-developers/browse_thread/thread/7fd5789a7da3f09`
|
||||||
|
|
||||||
It works like uuid.uuid4 except that tries to use os.urandom() if possible
|
It works like uuid.uuid4 except that tries to use os.urandom() if possible
|
||||||
and it XORs the output with the tokens uniquely associated with this machine.
|
and it XORs the output with the tokens uniquely associated with this machine.
|
||||||
@@ -263,6 +264,9 @@ REGEX_IPv4 = re.compile('(\d+)\.(\d+)\.(\d+)\.(\d+)')
|
|||||||
|
|
||||||
def is_valid_ip_address(address):
|
def is_valid_ip_address(address):
|
||||||
"""
|
"""
|
||||||
|
Examples:
|
||||||
|
Better than a thousand words::
|
||||||
|
|
||||||
>>> is_valid_ip_address('127.0')
|
>>> is_valid_ip_address('127.0')
|
||||||
False
|
False
|
||||||
>>> is_valid_ip_address('127.0.0.1')
|
>>> is_valid_ip_address('127.0.0.1')
|
||||||
|
|||||||
+226
-161
@@ -2,11 +2,13 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This file is part of the web2py Web Framework
|
| This file is part of the web2py Web Framework
|
||||||
Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
|
| Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
|
||||||
License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
|
| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
|
||||||
|
| Thanks to ga2arch for help with IS_IN_DB and IS_NOT_IN_DB on GAE
|
||||||
|
|
||||||
Thanks to ga2arch for help with IS_IN_DB and IS_NOT_IN_DB on GAE
|
Validators
|
||||||
|
-----------
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
@@ -144,11 +146,12 @@ class Validator(object):
|
|||||||
|
|
||||||
class IS_MATCH(Validator):
|
class IS_MATCH(Validator):
|
||||||
"""
|
"""
|
||||||
example::
|
Example:
|
||||||
|
Used as::
|
||||||
|
|
||||||
INPUT(_type='text', _name='name', requires=IS_MATCH('.+'))
|
INPUT(_type='text', _name='name', requires=IS_MATCH('.+'))
|
||||||
|
|
||||||
the argument of IS_MATCH is a regular expression::
|
The argument of IS_MATCH is a regular expression::
|
||||||
|
|
||||||
>>> IS_MATCH('.+')('hello')
|
>>> IS_MATCH('.+')('hello')
|
||||||
('hello', None)
|
('hello', None)
|
||||||
@@ -173,6 +176,7 @@ class IS_MATCH(Validator):
|
|||||||
|
|
||||||
>>> IS_MATCH('.+')('')
|
>>> IS_MATCH('.+')('')
|
||||||
('', 'invalid expression')
|
('', 'invalid expression')
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, expression, error_message='Invalid expression',
|
def __init__(self, expression, error_message='Invalid expression',
|
||||||
@@ -207,19 +211,21 @@ class IS_MATCH(Validator):
|
|||||||
|
|
||||||
class IS_EQUAL_TO(Validator):
|
class IS_EQUAL_TO(Validator):
|
||||||
"""
|
"""
|
||||||
example::
|
Example:
|
||||||
|
Used as::
|
||||||
|
|
||||||
INPUT(_type='text', _name='password')
|
INPUT(_type='text', _name='password')
|
||||||
INPUT(_type='text', _name='password2',
|
INPUT(_type='text', _name='password2',
|
||||||
requires=IS_EQUAL_TO(request.vars.password))
|
requires=IS_EQUAL_TO(request.vars.password))
|
||||||
|
|
||||||
the argument of IS_EQUAL_TO is a string
|
The argument of IS_EQUAL_TO is a string::
|
||||||
|
|
||||||
>>> IS_EQUAL_TO('aaa')('aaa')
|
>>> IS_EQUAL_TO('aaa')('aaa')
|
||||||
('aaa', None)
|
('aaa', None)
|
||||||
|
|
||||||
>>> IS_EQUAL_TO('aaa')('aab')
|
>>> IS_EQUAL_TO('aaa')('aab')
|
||||||
('aab', 'no match')
|
('aab', 'no match')
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, expression, error_message='No match'):
|
def __init__(self, expression, error_message='No match'):
|
||||||
@@ -234,18 +240,20 @@ class IS_EQUAL_TO(Validator):
|
|||||||
|
|
||||||
class IS_EXPR(Validator):
|
class IS_EXPR(Validator):
|
||||||
"""
|
"""
|
||||||
example::
|
Example:
|
||||||
|
Used as::
|
||||||
|
|
||||||
INPUT(_type='text', _name='name',
|
INPUT(_type='text', _name='name',
|
||||||
requires=IS_EXPR('5 < int(value) < 10'))
|
requires=IS_EXPR('5 < int(value) < 10'))
|
||||||
|
|
||||||
the argument of IS_EXPR must be python condition::
|
The argument of IS_EXPR must be python condition::
|
||||||
|
|
||||||
>>> IS_EXPR('int(value) < 2')('1')
|
>>> IS_EXPR('int(value) < 2')('1')
|
||||||
('1', None)
|
('1', None)
|
||||||
|
|
||||||
>>> IS_EXPR('int(value) < 2')('2')
|
>>> IS_EXPR('int(value) < 2')('2')
|
||||||
('2', 'invalid expression')
|
('2', 'invalid expression')
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, expression, error_message='Invalid expression', environment=None):
|
def __init__(self, expression, error_message='Invalid expression', environment=None):
|
||||||
@@ -269,22 +277,25 @@ class IS_LENGTH(Validator):
|
|||||||
Checks if length of field's value fits between given boundaries. Works
|
Checks if length of field's value fits between given boundaries. Works
|
||||||
for both text and file inputs.
|
for both text and file inputs.
|
||||||
|
|
||||||
Arguments:
|
Args:
|
||||||
|
|
||||||
maxsize: maximum allowed length / size
|
maxsize: maximum allowed length / size
|
||||||
minsize: minimum allowed length / size
|
minsize: minimum allowed length / size
|
||||||
|
|
||||||
Examples::
|
Examples:
|
||||||
|
Check if text string is shorter than 33 characters::
|
||||||
|
|
||||||
#Check if text string is shorter than 33 characters:
|
|
||||||
INPUT(_type='text', _name='name', requires=IS_LENGTH(32))
|
INPUT(_type='text', _name='name', requires=IS_LENGTH(32))
|
||||||
|
|
||||||
#Check if password string is longer than 5 characters:
|
Check if password string is longer than 5 characters::
|
||||||
|
|
||||||
INPUT(_type='password', _name='name', requires=IS_LENGTH(minsize=6))
|
INPUT(_type='password', _name='name', requires=IS_LENGTH(minsize=6))
|
||||||
|
|
||||||
#Check if uploaded file has size between 1KB and 1MB:
|
Check if uploaded file has size between 1KB and 1MB::
|
||||||
|
|
||||||
INPUT(_type='file', _name='name', requires=IS_LENGTH(1048576, 1024))
|
INPUT(_type='file', _name='name', requires=IS_LENGTH(1048576, 1024))
|
||||||
|
|
||||||
|
Other examples::
|
||||||
|
|
||||||
>>> IS_LENGTH()('')
|
>>> IS_LENGTH()('')
|
||||||
('', None)
|
('', None)
|
||||||
>>> IS_LENGTH()('1234567890')
|
>>> IS_LENGTH()('1234567890')
|
||||||
@@ -339,7 +350,9 @@ class IS_LENGTH(Validator):
|
|||||||
|
|
||||||
class IS_JSON(Validator):
|
class IS_JSON(Validator):
|
||||||
"""
|
"""
|
||||||
example::
|
Example:
|
||||||
|
Used as::
|
||||||
|
|
||||||
INPUT(_type='text', _name='name',
|
INPUT(_type='text', _name='name',
|
||||||
requires=IS_JSON(error_message="This is not a valid json input")
|
requires=IS_JSON(error_message="This is not a valid json input")
|
||||||
|
|
||||||
@@ -371,12 +384,13 @@ class IS_JSON(Validator):
|
|||||||
|
|
||||||
class IS_IN_SET(Validator):
|
class IS_IN_SET(Validator):
|
||||||
"""
|
"""
|
||||||
example::
|
Example:
|
||||||
|
Used as::
|
||||||
|
|
||||||
INPUT(_type='text', _name='name',
|
INPUT(_type='text', _name='name',
|
||||||
requires=IS_IN_SET(['max', 'john'],zero=''))
|
requires=IS_IN_SET(['max', 'john'],zero=''))
|
||||||
|
|
||||||
the argument of IS_IN_SET must be a list or set
|
The argument of IS_IN_SET must be a list or set::
|
||||||
|
|
||||||
>>> IS_IN_SET(['max', 'john'])('max')
|
>>> IS_IN_SET(['max', 'john'])('max')
|
||||||
('max', None)
|
('max', None)
|
||||||
@@ -395,6 +409,7 @@ class IS_IN_SET(Validator):
|
|||||||
('1', None)
|
('1', None)
|
||||||
>>> IS_IN_SET([('id1','first label'), ('id2','second label')])('id1') # Redundant way
|
>>> IS_IN_SET([('id1','first label'), ('id2','second label')])('id1') # Redundant way
|
||||||
('id1', None)
|
('id1', None)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@@ -463,7 +478,8 @@ regex2 = re.compile('%\(([^\)]+)\)\d*(?:\.\d+)?[a-zA-Z]')
|
|||||||
|
|
||||||
class IS_IN_DB(Validator):
|
class IS_IN_DB(Validator):
|
||||||
"""
|
"""
|
||||||
example::
|
Example:
|
||||||
|
Used as::
|
||||||
|
|
||||||
INPUT(_type='text', _name='name',
|
INPUT(_type='text', _name='name',
|
||||||
requires=IS_IN_DB(db, db.mytable.myfield, zero=''))
|
requires=IS_IN_DB(db, db.mytable.myfield, zero=''))
|
||||||
@@ -611,7 +627,8 @@ class IS_IN_DB(Validator):
|
|||||||
|
|
||||||
class IS_NOT_IN_DB(Validator):
|
class IS_NOT_IN_DB(Validator):
|
||||||
"""
|
"""
|
||||||
example::
|
Example:
|
||||||
|
Used as::
|
||||||
|
|
||||||
INPUT(_type='text', _name='name', requires=IS_NOT_IN_DB(db, db.table))
|
INPUT(_type='text', _name='name', requires=IS_NOT_IN_DB(db, db.table))
|
||||||
|
|
||||||
@@ -688,14 +705,15 @@ def range_error_message(error_message, what_to_enter, minimum, maximum):
|
|||||||
|
|
||||||
class IS_INT_IN_RANGE(Validator):
|
class IS_INT_IN_RANGE(Validator):
|
||||||
"""
|
"""
|
||||||
Determine that the argument is (or can be represented as) an int,
|
Determines that the argument is (or can be represented as) an int,
|
||||||
and that it falls within the specified range. The range is interpreted
|
and that it falls within the specified range. The range is interpreted
|
||||||
in the Pythonic way, so the test is: min <= value < max.
|
in the Pythonic way, so the test is: min <= value < max.
|
||||||
|
|
||||||
The minimum and maximum limits can be None, meaning no lower or upper limit,
|
The minimum and maximum limits can be None, meaning no lower or upper limit,
|
||||||
respectively.
|
respectively.
|
||||||
|
|
||||||
example::
|
Example:
|
||||||
|
Used as::
|
||||||
|
|
||||||
INPUT(_type='text', _name='name', requires=IS_INT_IN_RANGE(0, 10))
|
INPUT(_type='text', _name='name', requires=IS_INT_IN_RANGE(0, 10))
|
||||||
|
|
||||||
@@ -756,14 +774,15 @@ def str2dec(number):
|
|||||||
|
|
||||||
class IS_FLOAT_IN_RANGE(Validator):
|
class IS_FLOAT_IN_RANGE(Validator):
|
||||||
"""
|
"""
|
||||||
Determine that the argument is (or can be represented as) a float,
|
Determines that the argument is (or can be represented as) a float,
|
||||||
and that it falls within the specified inclusive range.
|
and that it falls within the specified inclusive range.
|
||||||
The comparison is made with native arithmetic.
|
The comparison is made with native arithmetic.
|
||||||
|
|
||||||
The minimum and maximum limits can be None, meaning no lower or upper limit,
|
The minimum and maximum limits can be None, meaning no lower or upper limit,
|
||||||
respectively.
|
respectively.
|
||||||
|
|
||||||
example::
|
Example:
|
||||||
|
Used as::
|
||||||
|
|
||||||
INPUT(_type='text', _name='name', requires=IS_FLOAT_IN_RANGE(0, 10))
|
INPUT(_type='text', _name='name', requires=IS_FLOAT_IN_RANGE(0, 10))
|
||||||
|
|
||||||
@@ -827,14 +846,15 @@ class IS_FLOAT_IN_RANGE(Validator):
|
|||||||
|
|
||||||
class IS_DECIMAL_IN_RANGE(Validator):
|
class IS_DECIMAL_IN_RANGE(Validator):
|
||||||
"""
|
"""
|
||||||
Determine that the argument is (or can be represented as) a Python Decimal,
|
Determines that the argument is (or can be represented as) a Python Decimal,
|
||||||
and that it falls within the specified inclusive range.
|
and that it falls within the specified inclusive range.
|
||||||
The comparison is made with Python Decimal arithmetic.
|
The comparison is made with Python Decimal arithmetic.
|
||||||
|
|
||||||
The minimum and maximum limits can be None, meaning no lower or upper limit,
|
The minimum and maximum limits can be None, meaning no lower or upper limit,
|
||||||
respectively.
|
respectively.
|
||||||
|
|
||||||
example::
|
Example:
|
||||||
|
Used as::
|
||||||
|
|
||||||
INPUT(_type='text', _name='name', requires=IS_DECIMAL_IN_RANGE(0, 10))
|
INPUT(_type='text', _name='name', requires=IS_DECIMAL_IN_RANGE(0, 10))
|
||||||
|
|
||||||
@@ -923,7 +943,8 @@ def is_empty(value, empty_regex=None):
|
|||||||
|
|
||||||
class IS_NOT_EMPTY(Validator):
|
class IS_NOT_EMPTY(Validator):
|
||||||
"""
|
"""
|
||||||
example::
|
Example:
|
||||||
|
Used as::
|
||||||
|
|
||||||
INPUT(_type='text', _name='name', requires=IS_NOT_EMPTY())
|
INPUT(_type='text', _name='name', requires=IS_NOT_EMPTY())
|
||||||
|
|
||||||
@@ -969,7 +990,8 @@ class IS_NOT_EMPTY(Validator):
|
|||||||
|
|
||||||
class IS_ALPHANUMERIC(IS_MATCH):
|
class IS_ALPHANUMERIC(IS_MATCH):
|
||||||
"""
|
"""
|
||||||
example::
|
Example:
|
||||||
|
Used as::
|
||||||
|
|
||||||
INPUT(_type='text', _name='name', requires=IS_ALPHANUMERIC())
|
INPUT(_type='text', _name='name', requires=IS_ALPHANUMERIC())
|
||||||
|
|
||||||
@@ -997,24 +1019,25 @@ class IS_EMAIL(Validator):
|
|||||||
generally following the RFCs, except that we disallow quoted strings
|
generally following the RFCs, except that we disallow quoted strings
|
||||||
and permit underscores and leading numerics in subdomain labels
|
and permit underscores and leading numerics in subdomain labels
|
||||||
|
|
||||||
Arguments:
|
Args:
|
||||||
|
banned: regex text for disallowed address domains
|
||||||
- banned: regex text for disallowed address domains
|
forced: regex text for required address domains
|
||||||
- forced: regex text for required address domains
|
|
||||||
|
|
||||||
Both arguments can also be custom objects with a match(value) method.
|
Both arguments can also be custom objects with a match(value) method.
|
||||||
|
|
||||||
Examples::
|
Example:
|
||||||
|
Check for valid email address::
|
||||||
|
|
||||||
#Check for valid email address:
|
|
||||||
INPUT(_type='text', _name='name',
|
INPUT(_type='text', _name='name',
|
||||||
requires=IS_EMAIL())
|
requires=IS_EMAIL())
|
||||||
|
|
||||||
#Check for valid email address that can't be from a .com domain:
|
Check for valid email address that can't be from a .com domain::
|
||||||
|
|
||||||
INPUT(_type='text', _name='name',
|
INPUT(_type='text', _name='name',
|
||||||
requires=IS_EMAIL(banned='^.*\.com(|\..*)$'))
|
requires=IS_EMAIL(banned='^.*\.com(|\..*)$'))
|
||||||
|
|
||||||
#Check for valid email address that must be from a .edu domain:
|
Check for valid email address that must be from a .edu domain::
|
||||||
|
|
||||||
INPUT(_type='text', _name='name',
|
INPUT(_type='text', _name='name',
|
||||||
requires=IS_EMAIL(forced='^.*\.edu(|\..*)$'))
|
requires=IS_EMAIL(forced='^.*\.edu(|\..*)$'))
|
||||||
|
|
||||||
@@ -1125,7 +1148,9 @@ class IS_EMAIL(Validator):
|
|||||||
|
|
||||||
class IS_LIST_OF_EMAILS(object):
|
class IS_LIST_OF_EMAILS(object):
|
||||||
"""
|
"""
|
||||||
use as follows:
|
Example:
|
||||||
|
Used as::
|
||||||
|
|
||||||
Field('emails','list:string',
|
Field('emails','list:string',
|
||||||
widget=SQLFORM.widgets.text.widget,
|
widget=SQLFORM.widgets.text.widget,
|
||||||
requires=IS_LIST_OF_EMAILS(),
|
requires=IS_LIST_OF_EMAILS(),
|
||||||
@@ -1311,10 +1336,12 @@ def escape_unicode(string):
|
|||||||
converted into a URL escaped form based on its hexadecimal value.
|
converted into a URL escaped form based on its hexadecimal value.
|
||||||
For example, the unicode character '\u4e86' will become the string '%4e%86'
|
For example, the unicode character '\u4e86' will become the string '%4e%86'
|
||||||
|
|
||||||
:param string: unicode string, the unicode string to convert into an
|
Args:
|
||||||
|
string: unicode string, the unicode string to convert into an
|
||||||
escaped US-ASCII form
|
escaped US-ASCII form
|
||||||
:returns: the US-ASCII escaped form of the inputted string
|
|
||||||
:rtype: string
|
Returns:
|
||||||
|
string: the US-ASCII escaped form of the inputted string
|
||||||
|
|
||||||
@author: Jonathan Benn
|
@author: Jonathan Benn
|
||||||
'''
|
'''
|
||||||
@@ -1338,12 +1365,16 @@ def unicode_to_ascii_authority(authority):
|
|||||||
For example, u'www.Alliancefran\xe7aise.nu' will be converted into
|
For example, u'www.Alliancefran\xe7aise.nu' will be converted into
|
||||||
'www.xn--alliancefranaise-npb.nu'
|
'www.xn--alliancefranaise-npb.nu'
|
||||||
|
|
||||||
:param authority: unicode string, the URL authority component to convert,
|
Args:
|
||||||
|
authority: unicode string, the URL authority component to convert,
|
||||||
e.g. u'www.Alliancefran\xe7aise.nu'
|
e.g. u'www.Alliancefran\xe7aise.nu'
|
||||||
:returns: the US-ASCII character equivalent to the inputed authority,
|
|
||||||
|
Returns:
|
||||||
|
string: the US-ASCII character equivalent to the inputed authority,
|
||||||
e.g. 'www.xn--alliancefranaise-npb.nu'
|
e.g. 'www.xn--alliancefranaise-npb.nu'
|
||||||
:rtype: string
|
|
||||||
:raises Exception: if the function is not able to convert the inputed
|
Raises:
|
||||||
|
Exception: if the function is not able to convert the inputed
|
||||||
authority
|
authority
|
||||||
|
|
||||||
@author: Jonathan Benn
|
@author: Jonathan Benn
|
||||||
@@ -1398,12 +1429,14 @@ def unicode_to_ascii_url(url, prepend_scheme):
|
|||||||
converted into '%4E%2D'. Testing with Firefox v3.0.5 has shown that it can
|
converted into '%4E%2D'. Testing with Firefox v3.0.5 has shown that it can
|
||||||
understand this kind of URI encoding.
|
understand this kind of URI encoding.
|
||||||
|
|
||||||
:param url: unicode string, the URL to convert from unicode into US-ASCII
|
Args:
|
||||||
:param prepend_scheme: string, a protocol scheme to prepend to the URL if
|
url: unicode string, the URL to convert from unicode into US-ASCII
|
||||||
|
prepend_scheme: string, a protocol scheme to prepend to the URL if
|
||||||
we're having trouble parsing it.
|
we're having trouble parsing it.
|
||||||
e.g. "http". Input None to disable this functionality
|
e.g. "http". Input None to disable this functionality
|
||||||
:returns: a US-ASCII equivalent of the inputed url
|
|
||||||
:rtype: string
|
Returns:
|
||||||
|
string: a US-ASCII equivalent of the inputed url
|
||||||
|
|
||||||
@author: Jonathan Benn
|
@author: Jonathan Benn
|
||||||
'''
|
'''
|
||||||
@@ -1467,6 +1500,14 @@ class IS_GENERIC_URL(Validator):
|
|||||||
>>> IS_GENERIC_URL()('http://user@abc.com')
|
>>> IS_GENERIC_URL()('http://user@abc.com')
|
||||||
('http://user@abc.com', None)
|
('http://user@abc.com', None)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
error_message: a string, the error message to give the end user
|
||||||
|
if the URL does not validate
|
||||||
|
allowed_schemes: a list containing strings or None. Each element
|
||||||
|
is a scheme the inputed URL is allowed to use
|
||||||
|
prepend_scheme: a string, this scheme is prepended if it's
|
||||||
|
necessary to make the URL valid
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@@ -1475,14 +1516,6 @@ class IS_GENERIC_URL(Validator):
|
|||||||
allowed_schemes=None,
|
allowed_schemes=None,
|
||||||
prepend_scheme=None,
|
prepend_scheme=None,
|
||||||
):
|
):
|
||||||
"""
|
|
||||||
:param error_message: a string, the error message to give the end user
|
|
||||||
if the URL does not validate
|
|
||||||
:param allowed_schemes: a list containing strings or None. Each element
|
|
||||||
is a scheme the inputed URL is allowed to use
|
|
||||||
:param prepend_scheme: a string, this scheme is prepended if it's
|
|
||||||
necessary to make the URL valid
|
|
||||||
"""
|
|
||||||
|
|
||||||
self.error_message = error_message
|
self.error_message = error_message
|
||||||
if allowed_schemes is None:
|
if allowed_schemes is None:
|
||||||
@@ -1499,8 +1532,11 @@ class IS_GENERIC_URL(Validator):
|
|||||||
|
|
||||||
def __call__(self, value):
|
def __call__(self, value):
|
||||||
"""
|
"""
|
||||||
:param value: a string, the URL to validate
|
Args:
|
||||||
:returns: a tuple, where tuple[0] is the inputed value (possible
|
value: a string, the URL to validate
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
a tuple, where tuple[0] is the inputed value (possible
|
||||||
prepended with prepend_scheme), and tuple[1] is either
|
prepended with prepend_scheme), and tuple[1] is either
|
||||||
None (success!) or the string error_message
|
None (success!) or the string error_message
|
||||||
"""
|
"""
|
||||||
@@ -1881,6 +1917,13 @@ class IS_HTTP_URL(Validator):
|
|||||||
>>> IS_HTTP_URL()('http://user@1.2.3.4')
|
>>> IS_HTTP_URL()('http://user@1.2.3.4')
|
||||||
('http://user@1.2.3.4', None)
|
('http://user@1.2.3.4', None)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
error_message: a string, the error message to give the end user
|
||||||
|
if the URL does not validate
|
||||||
|
allowed_schemes: a list containing strings or None. Each element
|
||||||
|
is a scheme the inputed URL is allowed to use
|
||||||
|
prepend_scheme: a string, this scheme is prepended if it's
|
||||||
|
necessary to make the URL valid
|
||||||
"""
|
"""
|
||||||
|
|
||||||
GENERIC_VALID_IP = re.compile(
|
GENERIC_VALID_IP = re.compile(
|
||||||
@@ -1893,14 +1936,6 @@ class IS_HTTP_URL(Validator):
|
|||||||
allowed_schemes=None,
|
allowed_schemes=None,
|
||||||
prepend_scheme='http',
|
prepend_scheme='http',
|
||||||
):
|
):
|
||||||
"""
|
|
||||||
:param error_message: a string, the error message to give the end user
|
|
||||||
if the URL does not validate
|
|
||||||
:param allowed_schemes: a list containing strings or None. Each element
|
|
||||||
is a scheme the inputed URL is allowed to use
|
|
||||||
:param prepend_scheme: a string, this scheme is prepended if it's
|
|
||||||
necessary to make the URL valid
|
|
||||||
"""
|
|
||||||
|
|
||||||
self.error_message = error_message
|
self.error_message = error_message
|
||||||
if allowed_schemes is None:
|
if allowed_schemes is None:
|
||||||
@@ -1920,8 +1955,11 @@ class IS_HTTP_URL(Validator):
|
|||||||
|
|
||||||
def __call__(self, value):
|
def __call__(self, value):
|
||||||
"""
|
"""
|
||||||
:param value: a string, the URL to validate
|
Args:
|
||||||
:returns: a tuple, where tuple[0] is the inputed value
|
value: a string, the URL to validate
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
a tuple, where tuple[0] is the inputed value
|
||||||
(possible prepended with prepend_scheme), and tuple[1] is either
|
(possible prepended with prepend_scheme), and tuple[1] is either
|
||||||
None (success!) or the string error_message
|
None (success!) or the string error_message
|
||||||
"""
|
"""
|
||||||
@@ -1984,6 +2022,7 @@ class IS_HTTP_URL(Validator):
|
|||||||
class IS_URL(Validator):
|
class IS_URL(Validator):
|
||||||
"""
|
"""
|
||||||
Rejects a URL string if any of the following is true:
|
Rejects a URL string if any of the following is true:
|
||||||
|
|
||||||
* The string is empty or None
|
* The string is empty or None
|
||||||
* The string uses characters that are not allowed in a URL
|
* The string uses characters that are not allowed in a URL
|
||||||
* The string breaks any of the HTTP syntactic rules
|
* The string breaks any of the HTTP syntactic rules
|
||||||
@@ -1999,6 +2038,7 @@ class IS_URL(Validator):
|
|||||||
|
|
||||||
If the parameter mode='generic' is used, then this function's behavior
|
If the parameter mode='generic' is used, then this function's behavior
|
||||||
changes. It then rejects a URL string if any of the following is true:
|
changes. It then rejects a URL string if any of the following is true:
|
||||||
|
|
||||||
* The string is empty or None
|
* The string is empty or None
|
||||||
* The string uses characters that are not allowed in a URL
|
* The string uses characters that are not allowed in a URL
|
||||||
* The URL scheme specified (if one is specified) is not valid
|
* The URL scheme specified (if one is specified) is not valid
|
||||||
@@ -2025,6 +2065,14 @@ class IS_URL(Validator):
|
|||||||
be escaped using the standard '%20' type syntax. e.g. the unicode
|
be escaped using the standard '%20' type syntax. e.g. the unicode
|
||||||
character with hex code 0x4e86 will become '%4e%86'
|
character with hex code 0x4e86 will become '%4e%86'
|
||||||
|
|
||||||
|
Args:
|
||||||
|
error_message: a string, the error message to give the end user
|
||||||
|
if the URL does not validate
|
||||||
|
allowed_schemes: a list containing strings or None. Each element
|
||||||
|
is a scheme the inputed URL is allowed to use
|
||||||
|
prepend_scheme: a string, this scheme is prepended if it's
|
||||||
|
necessary to make the URL valid
|
||||||
|
|
||||||
Code Examples::
|
Code Examples::
|
||||||
|
|
||||||
INPUT(_type='text', _name='name', requires=IS_URL())
|
INPUT(_type='text', _name='name', requires=IS_URL())
|
||||||
@@ -2063,14 +2111,6 @@ class IS_URL(Validator):
|
|||||||
allowed_schemes=None,
|
allowed_schemes=None,
|
||||||
prepend_scheme='http',
|
prepend_scheme='http',
|
||||||
):
|
):
|
||||||
"""
|
|
||||||
:param error_message: a string, the error message to give the end user
|
|
||||||
if the URL does not validate
|
|
||||||
:param allowed_schemes: a list containing strings or None. Each element
|
|
||||||
is a scheme the inputed URL is allowed to use
|
|
||||||
:param prepend_scheme: a string, this scheme is prepended if it's
|
|
||||||
necessary to make the URL valid
|
|
||||||
"""
|
|
||||||
|
|
||||||
self.error_message = error_message
|
self.error_message = error_message
|
||||||
self.mode = mode.lower()
|
self.mode = mode.lower()
|
||||||
@@ -2090,8 +2130,11 @@ class IS_URL(Validator):
|
|||||||
|
|
||||||
def __call__(self, value):
|
def __call__(self, value):
|
||||||
"""
|
"""
|
||||||
:param value: a unicode or regular string, the URL to validate
|
Args:
|
||||||
:returns: a (string, string) tuple, where tuple[0] is the modified
|
value: a unicode or regular string, the URL to validate
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
a (string, string) tuple, where tuple[0] is the modified
|
||||||
input value and tuple[1] is either None (success!) or the
|
input value and tuple[1] is either None (success!) or the
|
||||||
string error_message. The input value will never be modified in the
|
string error_message. The input value will never be modified in the
|
||||||
case of an error. However, if there is success then the input URL
|
case of an error. However, if there is success then the input URL
|
||||||
@@ -2135,7 +2178,8 @@ regex_time = re.compile(
|
|||||||
|
|
||||||
class IS_TIME(Validator):
|
class IS_TIME(Validator):
|
||||||
"""
|
"""
|
||||||
example::
|
Example:
|
||||||
|
Use as::
|
||||||
|
|
||||||
INPUT(_type='text', _name='name', requires=IS_TIME())
|
INPUT(_type='text', _name='name', requires=IS_TIME())
|
||||||
|
|
||||||
@@ -2144,7 +2188,7 @@ class IS_TIME(Validator):
|
|||||||
hh:mm [am/pm]
|
hh:mm [am/pm]
|
||||||
hh [am/pm]
|
hh [am/pm]
|
||||||
|
|
||||||
[am/pm] is optional, ':' can be replaced by any other non-space non-digit
|
[am/pm] is optional, ':' can be replaced by any other non-space non-digit::
|
||||||
|
|
||||||
>>> IS_TIME()('21:30')
|
>>> IS_TIME()('21:30')
|
||||||
(datetime.time(21, 30), None)
|
(datetime.time(21, 30), None)
|
||||||
@@ -2171,7 +2215,8 @@ class IS_TIME(Validator):
|
|||||||
>>> IS_TIME()('21:30::')
|
>>> IS_TIME()('21:30::')
|
||||||
('21:30::', 'enter time as hh:mm:ss (seconds, am, pm optional)')
|
('21:30::', 'enter time as hh:mm:ss (seconds, am, pm optional)')
|
||||||
>>> IS_TIME()('')
|
>>> IS_TIME()('')
|
||||||
('', 'enter time as hh:mm:ss (seconds, am, pm optional)')
|
('', 'enter time as hh:mm:ss (seconds, am, pm optional)')ù
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, error_message='Enter time as hh:mm:ss (seconds, am, pm optional)'):
|
def __init__(self, error_message='Enter time as hh:mm:ss (seconds, am, pm optional)'):
|
||||||
@@ -2215,19 +2260,18 @@ utc = UTC()
|
|||||||
|
|
||||||
class IS_DATE(Validator):
|
class IS_DATE(Validator):
|
||||||
"""
|
"""
|
||||||
example::
|
Examples:
|
||||||
|
Use as::
|
||||||
|
|
||||||
INPUT(_type='text', _name='name', requires=IS_DATE())
|
INPUT(_type='text', _name='name', requires=IS_DATE())
|
||||||
|
|
||||||
date has to be in the ISO8960 format YYYY-MM-DD
|
date has to be in the ISO8960 format YYYY-MM-DD
|
||||||
|
timezome must be None or a pytz.timezone("America/Chicago") object
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, format='%Y-%m-%d',
|
def __init__(self, format='%Y-%m-%d',
|
||||||
error_message='Enter date as %(format)s',
|
error_message='Enter date as %(format)s',
|
||||||
timezone = None):
|
timezone = None):
|
||||||
"""
|
|
||||||
timezome must be None or a pytz.timezone("America/Chicago") object
|
|
||||||
"""
|
|
||||||
self.format = translate(format)
|
self.format = translate(format)
|
||||||
self.error_message = str(error_message)
|
self.error_message = str(error_message)
|
||||||
self.timezone = timezone
|
self.timezone = timezone
|
||||||
@@ -2270,11 +2314,13 @@ class IS_DATE(Validator):
|
|||||||
|
|
||||||
class IS_DATETIME(Validator):
|
class IS_DATETIME(Validator):
|
||||||
"""
|
"""
|
||||||
example::
|
Examples:
|
||||||
|
Use as::
|
||||||
|
|
||||||
INPUT(_type='text', _name='name', requires=IS_DATETIME())
|
INPUT(_type='text', _name='name', requires=IS_DATETIME())
|
||||||
|
|
||||||
datetime has to be in the ISO8960 format YYYY-MM-DD hh:mm:ss
|
datetime has to be in the ISO8960 format YYYY-MM-DD hh:mm:ss
|
||||||
|
timezome must be None or a pytz.timezone("America/Chicago") object
|
||||||
"""
|
"""
|
||||||
|
|
||||||
isodatetime = '%Y-%m-%d %H:%M:%S'
|
isodatetime = '%Y-%m-%d %H:%M:%S'
|
||||||
@@ -2299,9 +2345,6 @@ class IS_DATETIME(Validator):
|
|||||||
def __init__(self, format='%Y-%m-%d %H:%M:%S',
|
def __init__(self, format='%Y-%m-%d %H:%M:%S',
|
||||||
error_message='Enter date and time as %(format)s',
|
error_message='Enter date and time as %(format)s',
|
||||||
timezone=None):
|
timezone=None):
|
||||||
"""
|
|
||||||
timezome must be None or a pytz.timezone("America/Chicago") object
|
|
||||||
"""
|
|
||||||
self.format = translate(format)
|
self.format = translate(format)
|
||||||
self.error_message = str(error_message)
|
self.error_message = str(error_message)
|
||||||
self.extremes = {}
|
self.extremes = {}
|
||||||
@@ -2341,7 +2384,8 @@ class IS_DATETIME(Validator):
|
|||||||
|
|
||||||
class IS_DATE_IN_RANGE(IS_DATE):
|
class IS_DATE_IN_RANGE(IS_DATE):
|
||||||
"""
|
"""
|
||||||
example::
|
Examples:
|
||||||
|
Use as::
|
||||||
|
|
||||||
>>> v = IS_DATE_IN_RANGE(minimum=datetime.date(2008,1,1), \
|
>>> v = IS_DATE_IN_RANGE(minimum=datetime.date(2008,1,1), \
|
||||||
maximum=datetime.date(2009,12,31), \
|
maximum=datetime.date(2009,12,31), \
|
||||||
@@ -2396,8 +2440,8 @@ class IS_DATE_IN_RANGE(IS_DATE):
|
|||||||
|
|
||||||
class IS_DATETIME_IN_RANGE(IS_DATETIME):
|
class IS_DATETIME_IN_RANGE(IS_DATETIME):
|
||||||
"""
|
"""
|
||||||
example::
|
Examples:
|
||||||
|
Use as::
|
||||||
>>> v = IS_DATETIME_IN_RANGE(\
|
>>> v = IS_DATETIME_IN_RANGE(\
|
||||||
minimum=datetime.datetime(2008,1,1,12,20), \
|
minimum=datetime.datetime(2008,1,1,12,20), \
|
||||||
maximum=datetime.datetime(2009,12,31,12,20), \
|
maximum=datetime.datetime(2009,12,31,12,20), \
|
||||||
@@ -2413,6 +2457,7 @@ class IS_DATETIME_IN_RANGE(IS_DATETIME):
|
|||||||
|
|
||||||
>>> v(datetime.datetime(2010,3,3,0,0))
|
>>> v(datetime.datetime(2010,3,3,0,0))
|
||||||
(datetime.datetime(2010, 3, 3, 0, 0), 'oops')
|
(datetime.datetime(2010, 3, 3, 0, 0), 'oops')
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
minimum=None,
|
minimum=None,
|
||||||
@@ -2484,12 +2529,13 @@ class IS_LIST_OF(Validator):
|
|||||||
|
|
||||||
class IS_LOWER(Validator):
|
class IS_LOWER(Validator):
|
||||||
"""
|
"""
|
||||||
convert to lower case
|
Converts to lower case::
|
||||||
|
|
||||||
>>> IS_LOWER()('ABC')
|
>>> IS_LOWER()('ABC')
|
||||||
('abc', None)
|
('abc', None)
|
||||||
>>> IS_LOWER()('Ñ')
|
>>> IS_LOWER()('Ñ')
|
||||||
('\\xc3\\xb1', None)
|
('\\xc3\\xb1', None)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __call__(self, value):
|
def __call__(self, value):
|
||||||
@@ -2498,12 +2544,13 @@ class IS_LOWER(Validator):
|
|||||||
|
|
||||||
class IS_UPPER(Validator):
|
class IS_UPPER(Validator):
|
||||||
"""
|
"""
|
||||||
convert to upper case
|
Converts to upper case::
|
||||||
|
|
||||||
>>> IS_UPPER()('abc')
|
>>> IS_UPPER()('abc')
|
||||||
('ABC', None)
|
('ABC', None)
|
||||||
>>> IS_UPPER()('ñ')
|
>>> IS_UPPER()('ñ')
|
||||||
('\\xc3\\x91', None)
|
('\\xc3\\x91', None)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __call__(self, value):
|
def __call__(self, value):
|
||||||
@@ -2512,7 +2559,7 @@ class IS_UPPER(Validator):
|
|||||||
|
|
||||||
def urlify(s, maxlen=80, keep_underscores=False):
|
def urlify(s, maxlen=80, keep_underscores=False):
|
||||||
"""
|
"""
|
||||||
Convert incoming string to a simplified ASCII subset.
|
Converts incoming string to a simplified ASCII subset.
|
||||||
if (keep_underscores): underscores are retained in the string
|
if (keep_underscores): underscores are retained in the string
|
||||||
else: underscores are translated to hyphens (default)
|
else: underscores are translated to hyphens (default)
|
||||||
"""
|
"""
|
||||||
@@ -2536,7 +2583,7 @@ def urlify(s, maxlen=80, keep_underscores=False):
|
|||||||
|
|
||||||
class IS_SLUG(Validator):
|
class IS_SLUG(Validator):
|
||||||
"""
|
"""
|
||||||
convert arbitrary text string to a slug
|
converts arbitrary text string to a slug::
|
||||||
|
|
||||||
>>> IS_SLUG()('abc123')
|
>>> IS_SLUG()('abc123')
|
||||||
('abc123', None)
|
('abc123', None)
|
||||||
@@ -2596,7 +2643,7 @@ class IS_SLUG(Validator):
|
|||||||
|
|
||||||
class ANY_OF(Validator):
|
class ANY_OF(Validator):
|
||||||
"""
|
"""
|
||||||
test if any of the validators in a list return successfully
|
Tests if any of the validators in a list returns successfully::
|
||||||
|
|
||||||
>>> ANY_OF([IS_EMAIL(),IS_ALPHANUMERIC()])('a@b.co')
|
>>> ANY_OF([IS_EMAIL(),IS_ALPHANUMERIC()])('a@b.co')
|
||||||
('a@b.co', None)
|
('a@b.co', None)
|
||||||
@@ -2606,6 +2653,7 @@ class ANY_OF(Validator):
|
|||||||
('@ab.co', 'enter only letters, numbers, and underscore')
|
('@ab.co', 'enter only letters, numbers, and underscore')
|
||||||
>>> ANY_OF([IS_ALPHANUMERIC(),IS_EMAIL()])('@ab.co')
|
>>> ANY_OF([IS_ALPHANUMERIC(),IS_EMAIL()])('@ab.co')
|
||||||
('@ab.co', 'enter a valid email address')
|
('@ab.co', 'enter a valid email address')
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, subs):
|
def __init__(self, subs):
|
||||||
@@ -2628,7 +2676,7 @@ class ANY_OF(Validator):
|
|||||||
|
|
||||||
class IS_EMPTY_OR(Validator):
|
class IS_EMPTY_OR(Validator):
|
||||||
"""
|
"""
|
||||||
dummy class for testing IS_EMPTY_OR
|
Dummy class for testing IS_EMPTY_OR::
|
||||||
|
|
||||||
>>> IS_EMPTY_OR(IS_EMAIL())('abc@def.com')
|
>>> IS_EMPTY_OR(IS_EMAIL())('abc@def.com')
|
||||||
('abc@def.com', None)
|
('abc@def.com', None)
|
||||||
@@ -2694,7 +2742,8 @@ IS_NULL_OR = IS_EMPTY_OR # for backward compatibility
|
|||||||
|
|
||||||
class CLEANUP(Validator):
|
class CLEANUP(Validator):
|
||||||
"""
|
"""
|
||||||
example::
|
Examples:
|
||||||
|
Use as::
|
||||||
|
|
||||||
INPUT(_type='text', _name='name', requires=CLEANUP())
|
INPUT(_type='text', _name='name', requires=CLEANUP())
|
||||||
|
|
||||||
@@ -2800,7 +2849,8 @@ class LazyCrypt(object):
|
|||||||
|
|
||||||
class CRYPT(object):
|
class CRYPT(object):
|
||||||
"""
|
"""
|
||||||
example::
|
Examples:
|
||||||
|
Use as::
|
||||||
|
|
||||||
INPUT(_type='text', _name='name', requires=CRYPT())
|
INPUT(_type='text', _name='name', requires=CRYPT())
|
||||||
|
|
||||||
@@ -2914,7 +2964,7 @@ otherset = frozenset(
|
|||||||
|
|
||||||
|
|
||||||
def calc_entropy(string):
|
def calc_entropy(string):
|
||||||
" calculate a simple entropy for a given string "
|
" calculates a simple entropy for a given string "
|
||||||
import math
|
import math
|
||||||
alphabet = 0 # alphabet size
|
alphabet = 0 # alphabet size
|
||||||
other = set()
|
other = set()
|
||||||
@@ -2946,7 +2996,8 @@ def calc_entropy(string):
|
|||||||
|
|
||||||
class IS_STRONG(object):
|
class IS_STRONG(object):
|
||||||
"""
|
"""
|
||||||
example::
|
Examples:
|
||||||
|
Use as::
|
||||||
|
|
||||||
INPUT(_type='password', _name='passwd',
|
INPUT(_type='password', _name='passwd',
|
||||||
requires=IS_STRONG(min=10, special=2, upper=2))
|
requires=IS_STRONG(min=10, special=2, upper=2))
|
||||||
@@ -3098,8 +3149,7 @@ class IS_IMAGE(Validator):
|
|||||||
Code parts taken from
|
Code parts taken from
|
||||||
http://mail.python.org/pipermail/python-list/2007-June/617126.html
|
http://mail.python.org/pipermail/python-list/2007-June/617126.html
|
||||||
|
|
||||||
Arguments:
|
Args:
|
||||||
|
|
||||||
extensions: iterable containing allowed *lowercase* image file extensions
|
extensions: iterable containing allowed *lowercase* image file extensions
|
||||||
('jpg' extension of uploaded file counts as 'jpeg')
|
('jpg' extension of uploaded file counts as 'jpeg')
|
||||||
maxsize: iterable containing maximum width and height of the image
|
maxsize: iterable containing maximum width and height of the image
|
||||||
@@ -3107,16 +3157,18 @@ class IS_IMAGE(Validator):
|
|||||||
|
|
||||||
Use (-1, -1) as minsize to pass image size check.
|
Use (-1, -1) as minsize to pass image size check.
|
||||||
|
|
||||||
Examples::
|
Examples:
|
||||||
|
Check if uploaded file is in any of supported image formats:
|
||||||
|
|
||||||
#Check if uploaded file is in any of supported image formats:
|
|
||||||
INPUT(_type='file', _name='name', requires=IS_IMAGE())
|
INPUT(_type='file', _name='name', requires=IS_IMAGE())
|
||||||
|
|
||||||
#Check if uploaded file is either JPEG or PNG:
|
Check if uploaded file is either JPEG or PNG:
|
||||||
|
|
||||||
INPUT(_type='file', _name='name',
|
INPUT(_type='file', _name='name',
|
||||||
requires=IS_IMAGE(extensions=('jpeg', 'png')))
|
requires=IS_IMAGE(extensions=('jpeg', 'png')))
|
||||||
|
|
||||||
#Check if uploaded file is PNG with maximum size of 200x200 pixels:
|
Check if uploaded file is PNG with maximum size of 200x200 pixels:
|
||||||
|
|
||||||
INPUT(_type='file', _name='name',
|
INPUT(_type='file', _name='name',
|
||||||
requires=IS_IMAGE(extensions=('png'), maxsize=(200, 200)))
|
requires=IS_IMAGE(extensions=('png'), maxsize=(200, 200)))
|
||||||
"""
|
"""
|
||||||
@@ -3200,8 +3252,7 @@ class IS_UPLOAD_FILENAME(Validator):
|
|||||||
Does *not* ensure the file type in any way. Returns validation failure
|
Does *not* ensure the file type in any way. Returns validation failure
|
||||||
if no data was uploaded.
|
if no data was uploaded.
|
||||||
|
|
||||||
Arguments::
|
Args:
|
||||||
|
|
||||||
filename: filename (before dot) regex
|
filename: filename (before dot) regex
|
||||||
extension: extension (after dot) regex
|
extension: extension (after dot) regex
|
||||||
lastdot: which dot should be used as a filename / extension separator:
|
lastdot: which dot should be used as a filename / extension separator:
|
||||||
@@ -3213,22 +3264,25 @@ class IS_UPLOAD_FILENAME(Validator):
|
|||||||
If there is no dot present, extension checks will be done against empty
|
If there is no dot present, extension checks will be done against empty
|
||||||
string and filename checks against whole value.
|
string and filename checks against whole value.
|
||||||
|
|
||||||
Examples::
|
Examples:
|
||||||
|
Check if file has a pdf extension (case insensitive):
|
||||||
|
|
||||||
#Check if file has a pdf extension (case insensitive):
|
|
||||||
INPUT(_type='file', _name='name',
|
INPUT(_type='file', _name='name',
|
||||||
requires=IS_UPLOAD_FILENAME(extension='pdf'))
|
requires=IS_UPLOAD_FILENAME(extension='pdf'))
|
||||||
|
|
||||||
#Check if file has a tar.gz extension and name starting with backup:
|
Check if file has a tar.gz extension and name starting with backup:
|
||||||
|
|
||||||
INPUT(_type='file', _name='name',
|
INPUT(_type='file', _name='name',
|
||||||
requires=IS_UPLOAD_FILENAME(filename='backup.*',
|
requires=IS_UPLOAD_FILENAME(filename='backup.*',
|
||||||
extension='tar.gz', lastdot=False))
|
extension='tar.gz', lastdot=False))
|
||||||
|
|
||||||
#Check if file has no extension and name matching README
|
Check if file has no extension and name matching README
|
||||||
#(case sensitive):
|
(case sensitive):
|
||||||
|
|
||||||
INPUT(_type='file', _name='name',
|
INPUT(_type='file', _name='name',
|
||||||
requires=IS_UPLOAD_FILENAME(filename='^README$',
|
requires=IS_UPLOAD_FILENAME(filename='^README$',
|
||||||
extension='^$', case=0))
|
extension='^$', case=0)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, filename=None, extension=None, lastdot=True, case=1,
|
def __init__(self, filename=None, extension=None, lastdot=True, case=1,
|
||||||
@@ -3273,20 +3327,20 @@ class IS_IPV4(Validator):
|
|||||||
|
|
||||||
IPv4 regex taken from: http://regexlib.com/REDetails.aspx?regexp_id=1411
|
IPv4 regex taken from: http://regexlib.com/REDetails.aspx?regexp_id=1411
|
||||||
|
|
||||||
Arguments:
|
Args:
|
||||||
|
|
||||||
minip: lowest allowed address; accepts:
|
minip: lowest allowed address; accepts:
|
||||||
str, eg. 192.168.0.1
|
|
||||||
list or tuple of octets, eg. [192, 168, 0, 1]
|
- str, eg. 192.168.0.1
|
||||||
|
- list or tuple of octets, eg. [192, 168, 0, 1]
|
||||||
maxip: highest allowed address; same as above
|
maxip: highest allowed address; same as above
|
||||||
invert: True to allow addresses only from outside of given range; note
|
invert: True to allow addresses only from outside of given range; note
|
||||||
that range boundaries are not matched this way
|
that range boundaries are not matched this way
|
||||||
is_localhost: localhost address treatment:
|
is_localhost: localhost address treatment:
|
||||||
None (default): indifferent
|
|
||||||
True (enforce): query address must match localhost address
|
- None (default): indifferent
|
||||||
(127.0.0.1)
|
- True (enforce): query address must match localhost address (127.0.0.1)
|
||||||
False (forbid): query address must not match localhost
|
- False (forbid): query address must not match localhost address
|
||||||
address
|
|
||||||
is_private: same as above, except that query address is checked against
|
is_private: same as above, except that query address is checked against
|
||||||
two address ranges: 172.16.0.0 - 172.31.255.255 and
|
two address ranges: 172.16.0.0 - 172.31.255.255 and
|
||||||
192.168.0.0 - 192.168.255.255
|
192.168.0.0 - 192.168.255.255
|
||||||
@@ -3294,7 +3348,7 @@ class IS_IPV4(Validator):
|
|||||||
one address range: 169.254.0.0 - 169.254.255.255
|
one address range: 169.254.0.0 - 169.254.255.255
|
||||||
|
|
||||||
Minip and maxip may also be lists or tuples of addresses in all above
|
Minip and maxip may also be lists or tuples of addresses in all above
|
||||||
forms (str, int, list / tuple), allowing setup of multiple address ranges:
|
forms (str, int, list / tuple), allowing setup of multiple address ranges::
|
||||||
|
|
||||||
minip = (minip1, minip2, ... minipN)
|
minip = (minip1, minip2, ... minipN)
|
||||||
| | |
|
| | |
|
||||||
@@ -3303,25 +3357,29 @@ class IS_IPV4(Validator):
|
|||||||
|
|
||||||
Longer iterable will be truncated to match length of shorter one.
|
Longer iterable will be truncated to match length of shorter one.
|
||||||
|
|
||||||
Examples::
|
Examples:
|
||||||
|
Check for valid IPv4 address:
|
||||||
|
|
||||||
#Check for valid IPv4 address:
|
|
||||||
INPUT(_type='text', _name='name', requires=IS_IPV4())
|
INPUT(_type='text', _name='name', requires=IS_IPV4())
|
||||||
|
|
||||||
#Check for valid IPv4 address belonging to specific range:
|
Check for valid IPv4 address belonging to specific range:
|
||||||
|
|
||||||
INPUT(_type='text', _name='name',
|
INPUT(_type='text', _name='name',
|
||||||
requires=IS_IPV4(minip='100.200.0.0', maxip='100.200.255.255'))
|
requires=IS_IPV4(minip='100.200.0.0', maxip='100.200.255.255'))
|
||||||
|
|
||||||
#Check for valid IPv4 address belonging to either 100.110.0.0 -
|
Check for valid IPv4 address belonging to either 100.110.0.0 -
|
||||||
#100.110.255.255 or 200.50.0.0 - 200.50.0.255 address range:
|
100.110.255.255 or 200.50.0.0 - 200.50.0.255 address range:
|
||||||
|
|
||||||
INPUT(_type='text', _name='name',
|
INPUT(_type='text', _name='name',
|
||||||
requires=IS_IPV4(minip=('100.110.0.0', '200.50.0.0'),
|
requires=IS_IPV4(minip=('100.110.0.0', '200.50.0.0'),
|
||||||
maxip=('100.110.255.255', '200.50.0.255')))
|
maxip=('100.110.255.255', '200.50.0.255')))
|
||||||
|
|
||||||
#Check for valid IPv4 address belonging to private address space:
|
Check for valid IPv4 address belonging to private address space:
|
||||||
|
|
||||||
INPUT(_type='text', _name='name', requires=IS_IPV4(is_private=True))
|
INPUT(_type='text', _name='name', requires=IS_IPV4(is_private=True))
|
||||||
|
|
||||||
#Check for valid IPv4 address that is not a localhost address:
|
Check for valid IPv4 address that is not a localhost address:
|
||||||
|
|
||||||
INPUT(_type='text', _name='name', requires=IS_IPV4(is_localhost=False))
|
INPUT(_type='text', _name='name', requires=IS_IPV4(is_localhost=False))
|
||||||
|
|
||||||
>>> IS_IPV4()('1.2.3.4')
|
>>> IS_IPV4()('1.2.3.4')
|
||||||
@@ -3358,6 +3416,7 @@ class IS_IPV4(Validator):
|
|||||||
('127.0.0.1', 'enter valid IPv4 address')
|
('127.0.0.1', 'enter valid IPv4 address')
|
||||||
>>> IS_IPV4(maxip='100.0.0.0', is_localhost=True)('127.0.0.1')
|
>>> IS_IPV4(maxip='100.0.0.0', is_localhost=True)('127.0.0.1')
|
||||||
('127.0.0.1', 'enter valid IPv4 address')
|
('127.0.0.1', 'enter valid IPv4 address')
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
regex = re.compile(
|
regex = re.compile(
|
||||||
@@ -3433,7 +3492,7 @@ class IS_IPV6(Validator):
|
|||||||
use the ipaddress library and falls back to contrib/ipaddr.py from Google
|
use the ipaddress library and falls back to contrib/ipaddr.py from Google
|
||||||
(https://code.google.com/p/ipaddr-py/)
|
(https://code.google.com/p/ipaddr-py/)
|
||||||
|
|
||||||
Arguments:
|
Args:
|
||||||
is_private: None (default): indifferent
|
is_private: None (default): indifferent
|
||||||
True (enforce): address must be in fc00::/7 range
|
True (enforce): address must be in fc00::/7 range
|
||||||
False (forbid): address must NOT be in fc00::/7 range
|
False (forbid): address must NOT be in fc00::/7 range
|
||||||
@@ -3447,17 +3506,20 @@ class IS_IPV6(Validator):
|
|||||||
subnets: value must be a member of at least one from list of subnets
|
subnets: value must be a member of at least one from list of subnets
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
Check for valid IPv6 address:
|
||||||
|
|
||||||
#Check for valid IPv6 address:
|
|
||||||
INPUT(_type='text', _name='name', requires=IS_IPV6())
|
INPUT(_type='text', _name='name', requires=IS_IPV6())
|
||||||
|
|
||||||
#Check for valid IPv6 address is a link_local address:
|
Check for valid IPv6 address is a link_local address:
|
||||||
|
|
||||||
INPUT(_type='text', _name='name', requires=IS_IPV6(is_link_local=True))
|
INPUT(_type='text', _name='name', requires=IS_IPV6(is_link_local=True))
|
||||||
|
|
||||||
#Check for valid IPv6 address that is Internet routeable:
|
Check for valid IPv6 address that is Internet routeable:
|
||||||
|
|
||||||
INPUT(_type='text', _name='name', requires=IS_IPV6(is_routeable=True))
|
INPUT(_type='text', _name='name', requires=IS_IPV6(is_routeable=True))
|
||||||
|
|
||||||
#Check for valid IPv6 address in specified subnet:
|
Check for valid IPv6 address in specified subnet:
|
||||||
|
|
||||||
INPUT(_type='text', _name='name', requires=IS_IPV6(subnets=['2001::/32'])
|
INPUT(_type='text', _name='name', requires=IS_IPV6(subnets=['2001::/32'])
|
||||||
|
|
||||||
>>> IS_IPV6()('fe80::126c:8ffa:fe22:b3af')
|
>>> IS_IPV6()('fe80::126c:8ffa:fe22:b3af')
|
||||||
@@ -3577,8 +3639,7 @@ class IS_IPADDRESS(Validator):
|
|||||||
Uses ipaddress library if found, falls back to PEP-3144 ipaddr.py from
|
Uses ipaddress library if found, falls back to PEP-3144 ipaddr.py from
|
||||||
Google (in contrib).
|
Google (in contrib).
|
||||||
|
|
||||||
Universal arguments:
|
Args:
|
||||||
|
|
||||||
minip: lowest allowed address; accepts:
|
minip: lowest allowed address; accepts:
|
||||||
str, eg. 192.168.0.1
|
str, eg. 192.168.0.1
|
||||||
list or tuple of octets, eg. [192, 168, 0, 1]
|
list or tuple of octets, eg. [192, 168, 0, 1]
|
||||||
@@ -3588,37 +3649,41 @@ class IS_IPADDRESS(Validator):
|
|||||||
|
|
||||||
IPv4 specific arguments:
|
IPv4 specific arguments:
|
||||||
|
|
||||||
is_localhost: localhost address treatment:
|
- is_localhost: localhost address treatment:
|
||||||
None (default): indifferent
|
|
||||||
True (enforce): query address must match localhost address
|
- None (default): indifferent
|
||||||
|
- True (enforce): query address must match localhost address
|
||||||
(127.0.0.1)
|
(127.0.0.1)
|
||||||
False (forbid): query address must not match localhost
|
- False (forbid): query address must not match localhost address
|
||||||
address
|
- is_private: same as above, except that query address is checked against
|
||||||
is_private: same as above, except that query address is checked against
|
|
||||||
two address ranges: 172.16.0.0 - 172.31.255.255 and
|
two address ranges: 172.16.0.0 - 172.31.255.255 and
|
||||||
192.168.0.0 - 192.168.255.255
|
192.168.0.0 - 192.168.255.255
|
||||||
is_automatic: same as above, except that query address is checked against
|
- is_automatic: same as above, except that query address is checked against
|
||||||
one address range: 169.254.0.0 - 169.254.255.255
|
one address range: 169.254.0.0 - 169.254.255.255
|
||||||
is_ipv4: None (default): indifferent
|
- is_ipv4: either:
|
||||||
True (enforce): must be an IPv4 address
|
|
||||||
False (forbid): must NOT be an IPv4 address
|
- None (default): indifferent
|
||||||
|
- True (enforce): must be an IPv4 address
|
||||||
|
- False (forbid): must NOT be an IPv4 address
|
||||||
|
|
||||||
IPv6 specific arguments:
|
IPv6 specific arguments:
|
||||||
|
|
||||||
is_link_local: Same as above but uses fe80::/10 range
|
- is_link_local: Same as above but uses fe80::/10 range
|
||||||
is_reserved: Same as above but uses IETF reserved range
|
- is_reserved: Same as above but uses IETF reserved range
|
||||||
is_mulicast: Same as above but uses ff00::/8 range
|
- is_mulicast: Same as above but uses ff00::/8 range
|
||||||
is_routeable: Similar to above but enforces not private, link_local,
|
- is_routeable: Similar to above but enforces not private, link_local,
|
||||||
reserved or multicast
|
reserved or multicast
|
||||||
is_6to4: Same as above but uses 2002::/16 range
|
- is_6to4: Same as above but uses 2002::/16 range
|
||||||
is_teredo: Same as above but uses 2001::/32 range
|
- is_teredo: Same as above but uses 2001::/32 range
|
||||||
subnets: value must be a member of at least one from list of subnets
|
- subnets: value must be a member of at least one from list of subnets
|
||||||
is_ipv6: None (default): indifferent
|
- is_ipv6: either:
|
||||||
True (enforce): must be an IPv6 address
|
|
||||||
False (forbid): must NOT be an IPv6 address
|
- None (default): indifferent
|
||||||
|
- True (enforce): must be an IPv6 address
|
||||||
|
- False (forbid): must NOT be an IPv6 address
|
||||||
|
|
||||||
Minip and maxip may also be lists or tuples of addresses in all above
|
Minip and maxip may also be lists or tuples of addresses in all above
|
||||||
forms (str, int, list / tuple), allowing setup of multiple address ranges:
|
forms (str, int, list / tuple), allowing setup of multiple address ranges::
|
||||||
|
|
||||||
minip = (minip1, minip2, ... minipN)
|
minip = (minip1, minip2, ... minipN)
|
||||||
| | |
|
| | |
|
||||||
|
|||||||
+14
-13
@@ -2,11 +2,12 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This file is part of the web2py Web Framework
|
| This file is part of the web2py Web Framework
|
||||||
Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
|
| Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
|
||||||
License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
|
| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
|
||||||
|
|
||||||
The widget is called from web2py.
|
The widget is called from web2py
|
||||||
|
----------------------------------
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
@@ -379,7 +380,7 @@ class web2pyDialog(object):
|
|||||||
t.start()
|
t.start()
|
||||||
|
|
||||||
def checkTaskBar(self):
|
def checkTaskBar(self):
|
||||||
""" Check taskbar status """
|
""" Checks taskbar status """
|
||||||
|
|
||||||
if self.tb.status:
|
if self.tb.status:
|
||||||
if self.tb.status[0] == self.tb.EnumStatus.QUIT:
|
if self.tb.status[0] == self.tb.EnumStatus.QUIT:
|
||||||
@@ -401,7 +402,7 @@ class web2pyDialog(object):
|
|||||||
self.root.after(1000, self.checkTaskBar)
|
self.root.after(1000, self.checkTaskBar)
|
||||||
|
|
||||||
def update(self, text):
|
def update(self, text):
|
||||||
""" Update app text """
|
""" Updates app text """
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.text.configure(state='normal')
|
self.text.configure(state='normal')
|
||||||
@@ -411,7 +412,7 @@ class web2pyDialog(object):
|
|||||||
pass # ## this should only happen in case app is destroyed
|
pass # ## this should only happen in case app is destroyed
|
||||||
|
|
||||||
def connect_pages(self):
|
def connect_pages(self):
|
||||||
""" Connect pages """
|
""" Connects pages """
|
||||||
#reset the menu
|
#reset the menu
|
||||||
available_apps = [arq for arq in os.listdir('applications/')
|
available_apps = [arq for arq in os.listdir('applications/')
|
||||||
if os.path.exists(
|
if os.path.exists(
|
||||||
@@ -423,7 +424,7 @@ class web2pyDialog(object):
|
|||||||
label=url, command=lambda u=url: start_browser(u))
|
label=url, command=lambda u=url: start_browser(u))
|
||||||
|
|
||||||
def quit(self, justHide=False):
|
def quit(self, justHide=False):
|
||||||
""" Finish the program execution """
|
""" Finishes the program execution """
|
||||||
if justHide:
|
if justHide:
|
||||||
self.root.withdraw()
|
self.root.withdraw()
|
||||||
else:
|
else:
|
||||||
@@ -450,13 +451,13 @@ class web2pyDialog(object):
|
|||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
def error(self, message):
|
def error(self, message):
|
||||||
""" Show error message """
|
""" Shows error message """
|
||||||
|
|
||||||
import tkMessageBox
|
import tkMessageBox
|
||||||
tkMessageBox.showerror('web2py start server', message)
|
tkMessageBox.showerror('web2py start server', message)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
""" Start web2py server """
|
""" Starts web2py server """
|
||||||
|
|
||||||
password = self.password.get()
|
password = self.password.get()
|
||||||
|
|
||||||
@@ -536,7 +537,7 @@ class web2pyDialog(object):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
""" Stop web2py server """
|
""" Stops web2py server """
|
||||||
|
|
||||||
self.button_start.configure(state='normal')
|
self.button_start.configure(state='normal')
|
||||||
self.button_stop.configure(state='disabled')
|
self.button_stop.configure(state='disabled')
|
||||||
@@ -549,7 +550,7 @@ class web2pyDialog(object):
|
|||||||
self.tb.SetServerStopped()
|
self.tb.SetServerStopped()
|
||||||
|
|
||||||
def update_canvas(self):
|
def update_canvas(self):
|
||||||
""" Update canvas """
|
""" Updates canvas """
|
||||||
|
|
||||||
try:
|
try:
|
||||||
t1 = os.path.getsize('httpserver.log')
|
t1 = os.path.getsize('httpserver.log')
|
||||||
@@ -1054,7 +1055,7 @@ def start_schedulers(options):
|
|||||||
|
|
||||||
|
|
||||||
def start(cron=True):
|
def start(cron=True):
|
||||||
""" Start server """
|
""" Starts server """
|
||||||
|
|
||||||
# ## get command line arguments
|
# ## get command line arguments
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -2,9 +2,9 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This file is part of the web2py Web Framework
|
| This file is part of the web2py Web Framework
|
||||||
Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
|
| Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
|
||||||
License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
|
| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from SimpleXMLRPCServer import SimpleXMLRPCDispatcher
|
from SimpleXMLRPCServer import SimpleXMLRPCDispatcher
|
||||||
|
|||||||
Reference in new issue
Block a user