Merge branch 'master' of github.com:web2py/web2py

This commit is contained in:
mdipierro committed 2015-03-31 14:45:59 -05:00
commit 1b39736561
4 files changed
+72 -91

No files matched your search

+49 -81
View File
@@ -287,8 +287,7 @@ class Mail(object):
self.result = {} self.result = {}
self.error = None self.error = None
def send( def send(self,
self,
to, to,
subject='[no subject]', subject='[no subject]',
message='[no message]', message='[no message]',
@@ -839,8 +838,7 @@ class Recaptcha(DIV):
API_SERVER = 'http://www.google.com/recaptcha/api' API_SERVER = 'http://www.google.com/recaptcha/api'
VERIFY_SERVER = 'http://www.google.com/recaptcha/api/verify' VERIFY_SERVER = 'http://www.google.com/recaptcha/api/verify'
def __init__( def __init__(self,
self,
request=None, request=None,
public_key='', public_key='',
private_key='', private_key='',
@@ -963,6 +961,7 @@ class Recaptcha(DIV):
captcha.append(DIV(self.errors['captcha'], _class='error')) captcha.append(DIV(self.errors['captcha'], _class='error'))
return XML(captcha).xml() return XML(captcha).xml()
# this should only be used for catcha and perhaps not even for that # this should only be used for catcha and perhaps not even for that
def addrow(form, a, b, c, style, _id, position=-1): def addrow(form, a, b, c, style, _id, position=-1):
if style == "divs": if style == "divs":
@@ -1099,8 +1098,7 @@ class Auth(object):
retrieve_username_subject='Username retrieve', retrieve_username_subject='Username retrieve',
retrieve_password='Your password is: %(password)s', retrieve_password='Your password is: %(password)s',
retrieve_password_subject='Password retrieve', retrieve_password_subject='Password retrieve',
reset_password= reset_password='Click on the link %(link)s to reset your password',
'Click on the link %(link)s to reset your password',
reset_password_subject='Password reset', reset_password_subject='Password reset',
invalid_reset_password='Invalid reset password', invalid_reset_password='Invalid reset password',
profile_updated='Profile updated', profile_updated='Profile updated',
@@ -1365,7 +1363,8 @@ class Auth(object):
# ## these are messages that can be customized # ## these are messages that can be customized
messages = self.messages = Messages(current.T) messages = self.messages = Messages(current.T)
messages.update(Auth.default_messages) messages.update(Auth.default_messages)
messages.update(ajax_failed_authentication=DIV(H4('NOT AUTHORIZED'), messages.update(ajax_failed_authentication=
DIV(H4('NOT AUTHORIZED'),
'Please ', 'Please ',
A('login', A('login',
_href=self.settings.login_url + _href=self.settings.login_url +
@@ -1392,7 +1391,7 @@ class Auth(object):
return next return next
def _get_user_id(self): def _get_user_id(self):
"accessor for auth.user_id" """accessor for auth.user_id"""
return self.user and self.user.id or None return self.user and self.user.id or None
user_id = property(_get_user_id, doc="user.id or None") user_id = property(_get_user_id, doc="user.id or None")
@@ -1787,8 +1786,10 @@ class Auth(object):
""" """
db = self.db db = self.db
if migrate is None: migrate = db._migrate if migrate is None:
if fake_migrate is None: fake_migrate = db._fake_migrate migrate = db._migrate
if fake_migrate is None:
fake_migrate = db._fake_migrate
settings = self.settings settings = self.settings
if username is None: if username is None:
username = settings.use_username username = settings.use_username
@@ -1895,8 +1896,7 @@ class Auth(object):
settings.table_group_name, settings.table_group_name,
Field('role', length=512, default='', Field('role', length=512, default='',
label=self.messages.label_role, label=self.messages.label_role,
requires=IS_NOT_IN_DB( requires=IS_NOT_IN_DB(db, '%s.role' % settings.table_group_name)),
db, '%s.role' % settings.table_group_name)),
Field('description', 'text', Field('description', 'text',
label=self.messages.label_description), label=self.messages.label_description),
*extra_fields, *extra_fields,
@@ -2116,8 +2116,7 @@ class Auth(object):
basic_realm = unicode(basic_auth_realm) basic_realm = unicode(basic_auth_realm)
elif basic_auth_realm is True: elif basic_auth_realm is True:
basic_realm = u'' + current.request.application basic_realm = u'' + current.request.application
http_401 = HTTP(401, u'Not Authorized', http_401 = HTTP(401, u'Not Authorized', **{'WWW-Authenticate': u'Basic realm="' + basic_realm + '"'})
**{'WWW-Authenticate': u'Basic realm="' + basic_realm + '"'})
if not basic or not basic[:6].lower() == 'basic ': if not basic or not basic[:6].lower() == 'basic ':
if basic_auth_realm: if basic_auth_realm:
raise http_401 raise http_401
@@ -2143,8 +2142,7 @@ class Auth(object):
delattr(user, key) delattr(user, key)
if self.settings.renew_session_onlogin: if self.settings.renew_session_onlogin:
current.session.renew(clear_session=not self.settings.keep_session_onlogin) current.session.renew(clear_session=not self.settings.keep_session_onlogin)
current.session.auth = Storage( current.session.auth = Storage(user=user,
user = user,
last_visit=current.request.now, last_visit=current.request.now,
expiration=self.settings.expiration, expiration=self.settings.expiration,
hmac_key=web2py_uuid()) hmac_key=web2py_uuid())
@@ -2178,8 +2176,7 @@ class Auth(object):
else: else:
# user not in database try other login methods # user not in database try other login methods
for login_method in self.settings.login_methods: for login_method in self.settings.login_methods:
if login_method != self and \ if login_method != self and login_method(username, password):
login_method(username, password):
self.user = username self.user = username
return username return username
return False return False
@@ -2196,20 +2193,14 @@ class Auth(object):
elif not fields.get(settings.userfield): elif not fields.get(settings.userfield):
raise ValueError("register_bare: " + raise ValueError("register_bare: " +
"userfield not provided or invalid") "userfield not provided or invalid")
fields[settings.passfield] = \ fields[settings.passfield] = settings.table_user[settings.passfield].validate(fields[settings.passfield])[0]
settings.table_user[settings.passfield].validate( user = self.get_or_create_user(fields, login=False, get=False, update_fields=self.settings.update_fields)
fields[settings.passfield])[0]
user = self.get_or_create_user(
fields, login=False, get=False,
update_fields=self.settings.update_fields)
if not user: if not user:
# get or create did not create a user (it ignores duplicate records) # get or create did not create a user (it ignores duplicate records)
return False return False
return user return user
def cas_login(self,
def cas_login(
self,
next=DEFAULT, next=DEFAULT,
onvalidation=DEFAULT, onvalidation=DEFAULT,
onaccept=DEFAULT, onaccept=DEFAULT,
@@ -2303,18 +2294,17 @@ class Auth(object):
raise HTTP(200, message) raise HTTP(200, message)
def _reset_two_factor_auth(self, session): def _reset_two_factor_auth(self, session):
'''When two-step authentication is enabled, this function is used to """When two-step authentication is enabled, this function is used to
clear the session after successfully completing second challenge clear the session after successfully completing second challenge
or when the maximum number of tries allowed has expired. or when the maximum number of tries allowed has expired.
''' """
session.auth_two_factor_user = None session.auth_two_factor_user = None
session.auth_two_factor = None session.auth_two_factor = None
session.auth_two_factor_enabled = False session.auth_two_factor_enabled = False
# Allow up to 4 attempts (the 1st one plus 3 more) # Allow up to 4 attempts (the 1st one plus 3 more)
session.auth_two_factor_tries_left = 3 session.auth_two_factor_tries_left = 3
def login( def login(self,
self,
next=DEFAULT, next=DEFAULT,
onvalidation=DEFAULT, onvalidation=DEFAULT,
onaccept=DEFAULT, onaccept=DEFAULT,
@@ -2673,8 +2663,7 @@ class Auth(object):
if not next is None: if not next is None:
redirect(next) redirect(next)
def register( def register(self,
self,
next=DEFAULT, next=DEFAULT,
onvalidation=DEFAULT, onvalidation=DEFAULT,
onaccept=DEFAULT, onaccept=DEFAULT,
@@ -2813,8 +2802,7 @@ class Auth(object):
return True return True
return False return False
def verify_email( def verify_email(self,
self,
next=DEFAULT, next=DEFAULT,
onaccept=DEFAULT, onaccept=DEFAULT,
log=DEFAULT, log=DEFAULT,
@@ -2847,8 +2835,7 @@ class Auth(object):
callback(onaccept, user) callback(onaccept, user)
redirect(next) redirect(next)
def retrieve_username( def retrieve_username(self,
self,
next=DEFAULT, next=DEFAULT,
onvalidation=DEFAULT, onvalidation=DEFAULT,
onaccept=DEFAULT, onaccept=DEFAULT,
@@ -2905,8 +2892,7 @@ class Auth(object):
username = ', '.join(u.username for u in users) username = ', '.join(u.username for u in users)
self.settings.mailer.send(to=form.vars.email, self.settings.mailer.send(to=form.vars.email,
subject=self.messages.retrieve_username_subject, subject=self.messages.retrieve_username_subject,
message=self.messages.retrieve_username message=self.messages.retrieve_username % dict(username=username))
% dict(username=username))
session.flash = self.messages.email_sent session.flash = self.messages.email_sent
for user in users: for user in users:
self.log_event(log, user) self.log_event(log, user)
@@ -2931,8 +2917,7 @@ class Auth(object):
password += random.choice(specials) password += random.choice(specials)
return ''.join(random.sample(password, len(password))) return ''.join(random.sample(password, len(password)))
def reset_password_deprecated( def reset_password_deprecated(self,
self,
next=DEFAULT, next=DEFAULT,
onvalidation=DEFAULT, onvalidation=DEFAULT,
onaccept=DEFAULT, onaccept=DEFAULT,
@@ -2991,8 +2976,7 @@ class Auth(object):
if self.settings.mailer and \ if self.settings.mailer and \
self.settings.mailer.send(to=form.vars.email, self.settings.mailer.send(to=form.vars.email,
subject=self.messages.retrieve_password_subject, subject=self.messages.retrieve_password_subject,
message=self.messages.retrieve_password message=self.messages.retrieve_password % dict(password=password)):
% dict(password=password)):
session.flash = self.messages.email_sent session.flash = self.messages.email_sent
else: else:
session.flash = self.messages.unable_to_send_email session.flash = self.messages.unable_to_send_email
@@ -3006,8 +2990,7 @@ class Auth(object):
table_user.email.requires = old_requires table_user.email.requires = old_requires
return form return form
def reset_password( def reset_password(self,
self,
next=DEFAULT, next=DEFAULT,
onvalidation=DEFAULT, onvalidation=DEFAULT,
onaccept=DEFAULT, onaccept=DEFAULT,
@@ -3071,8 +3054,7 @@ class Auth(object):
redirect(next, client_side=self.settings.client_side) redirect(next, client_side=self.settings.client_side)
return form return form
def request_reset_password( def request_reset_password(self,
self,
next=DEFAULT, next=DEFAULT,
onvalidation=DEFAULT, onvalidation=DEFAULT,
onaccept=DEFAULT, onaccept=DEFAULT,
@@ -3169,8 +3151,7 @@ class Auth(object):
return True return True
return False return False
def retrieve_password( def retrieve_password(self,
self,
next=DEFAULT, next=DEFAULT,
onvalidation=DEFAULT, onvalidation=DEFAULT,
onaccept=DEFAULT, onaccept=DEFAULT,
@@ -3181,8 +3162,7 @@ class Auth(object):
else: else:
return self.reset_password_deprecated(next, onvalidation, onaccept, log) return self.reset_password_deprecated(next, onvalidation, onaccept, log)
def change_password( def change_password(self,
self,
next=DEFAULT, next=DEFAULT,
onvalidation=DEFAULT, onvalidation=DEFAULT,
onaccept=DEFAULT, onaccept=DEFAULT,
@@ -3253,8 +3233,7 @@ class Auth(object):
redirect(next, client_side=self.settings.client_side) redirect(next, client_side=self.settings.client_side)
return form return form
def profile( def profile(self,
self,
next=DEFAULT, next=DEFAULT,
onvalidation=DEFAULT, onvalidation=DEFAULT,
onaccept=DEFAULT, onaccept=DEFAULT,
@@ -3615,8 +3594,7 @@ class Auth(object):
if group_id in self.user_groups: del self.user_groups[group_id] if group_id in self.user_groups: del self.user_groups[group_id]
return ret return ret
def has_permission( def has_permission(self,
self,
name='any', name='any',
table_name='', table_name='',
record_id=0, record_id=0,
@@ -3668,8 +3646,7 @@ class Auth(object):
table_name=table_name, record_id=record_id)) table_name=table_name, record_id=record_id))
return r return r
def add_permission( def add_permission(self,
self,
group_id, group_id,
name='any', name='any',
table_name='', table_name='',
@@ -3696,8 +3673,7 @@ class Auth(object):
record_id=record_id)) record_id=record_id))
return id return id
def del_permission( def del_permission(self,
self,
group_id, group_id,
name='any', name='any',
table_name='', table_name='',
@@ -3862,7 +3838,8 @@ class Auth(object):
force_render=False, force_render=False,
groups=None): groups=None):
if controller and function: resolve = False if controller and function:
resolve = False
if not hasattr(self, '_wiki'): if not hasattr(self, '_wiki'):
self._wiki = Wiki(self, render=render, self._wiki = Wiki(self, render=render,
@@ -3885,7 +3862,7 @@ class Auth(object):
if resolve: if resolve:
if slug: if slug:
wiki = self._wiki.read(slug, force_render) wiki = self._wiki.read(slug, force_render)
if isinstance(wiki, dict) and wiki.has_key('content'): if isinstance(wiki, dict) and wiki.has_key('content'): # FIXME: .has_key() is deprecated
# We don't want to return a dict object, just the wiki # We don't want to return a dict object, just the wiki
wiki = wiki['content'] wiki = wiki['content']
else: else:
@@ -4013,8 +3990,7 @@ class Crud(object):
return Auth.archive(form, archive_table=archive_table, return Auth.archive(form, archive_table=archive_table,
current_record=current_record) current_record=current_record)
def update( def update(self,
self,
table, table,
record, record,
next=DEFAULT, next=DEFAULT,
@@ -4125,8 +4101,7 @@ class Crud(object):
raise HTTP(401, serializers.json(dict(errors=form.errors))) raise HTTP(401, serializers.json(dict(errors=form.errors)))
return form return form
def create( def create(self,
self,
table, table,
next=DEFAULT, next=DEFAULT,
onvalidation=DEFAULT, onvalidation=DEFAULT,
@@ -4182,8 +4157,7 @@ class Crud(object):
return table._filter_fields(form.record, id=True) return table._filter_fields(form.record, id=True)
return form return form
def delete( def delete(self,
self,
table, table,
record_id, record_id,
next=DEFAULT, next=DEFAULT,
@@ -4237,8 +4211,7 @@ class Crud(object):
limitby=limitby)) limitby=limitby))
return rows return rows
def select( def select(self,
self,
table, table,
query=None, query=None,
fields=None, fields=None,
@@ -4382,8 +4355,7 @@ class Crud(object):
if request.post_vars and (chkval or field.type == 'id'): if request.post_vars and (chkval or field.type == 'id'):
if txtval and opval != '': if txtval and opval != '':
if field.type[0:10] == 'reference ': if field.type[0:10] == 'reference ':
refsearch.append(self.get_query(field, refsearch.append(self.get_query(field, opval, txtval, refsearch=True))
opval, txtval, refsearch=True))
elif validate: elif validate:
value, error = field.validate(txtval) value, error = field.validate(txtval)
if not error: if not error:
@@ -4477,8 +4449,7 @@ def universal_caller(f, *a, **b):
# Fill the arg_dict with name and value for the submitted, positional values # Fill the arg_dict with name and value for the submitted, positional values
for pos_index, pos_val in enumerate(a[:c]): for pos_index, pos_val in enumerate(a[:c]):
arg_dict[n[pos_index] arg_dict[n[pos_index]] = pos_val # n[pos_index] is the name of the argument
] = pos_val # n[pos_index] is the name of the argument
# There might be pos_args left, that are sent as named_values. Gather them as well. # There might be pos_args left, that are sent as named_values. Gather them as well.
# If a argument already is populated with values we simply replaces them. # If a argument already is populated with values we simply replaces them.
@@ -4856,7 +4827,6 @@ class Service(object):
-32603: ("Internal error", "Internal JSON-RPC error."), -32603: ("Internal error", "Internal JSON-RPC error."),
-32099: ("Server error", "Reserved for implementation-defined server-errors.")} -32099: ("Server error", "Reserved for implementation-defined server-errors.")}
def serve_jsonrpc(self): def serve_jsonrpc(self):
def return_response(id, result): def return_response(id, result):
return serializers.json({'version': '1.1', return serializers.json({'version': '1.1',
@@ -4952,8 +4922,6 @@ class Service(object):
return True return True
request = current.request request = current.request
response = current.response response = current.response
if not data: if not data:
@@ -5006,7 +4974,6 @@ class Service(object):
logger.warning('%s: %s\n%s' % (etype.__name__, eval, traceback.format_tb(etb))) logger.warning('%s: %s\n%s' % (etype.__name__, eval, traceback.format_tb(etb)))
return return_error(id, -32099, data=data) return return_error(id, -32099, data=data)
def serve_xmlrpc(self): def serve_xmlrpc(self):
request = current.request request = current.request
response = current.response response = current.response
@@ -5464,6 +5431,7 @@ class Expose(object):
class Wiki(object): class Wiki(object):
everybody = 'everybody' everybody = 'everybody'
rows_page = 25 rows_page = 25
def markmin_base(self, body): def markmin_base(self, body):
return MARKMIN(body, extra=self.settings.extra, return MARKMIN(body, extra=self.settings.extra,
url=True, environment=self.env, url=True, environment=self.env,
@@ -5825,7 +5793,8 @@ class Wiki(object):
db.wiki_page.body.default = \ db.wiki_page.body.default = \
'- Menu Item > @////index\n- - Submenu > http://web2py.com' '- Menu Item > @////index\n- - Submenu > http://web2py.com'
else: else:
db.wiki_page.body.default = db(db.wiki_page.id==from_template).select(db.wiki_page.body)[0].body if int(from_template) > 0 else '## %s\n\npage content' % title_guess db.wiki_page.body.default = db(db.wiki_page.id == from_template).select(db.wiki_page.body)[0].body \
if int(from_template) > 0 else '## %s\n\npage content' % title_guess
vars = current.request.post_vars vars = current.request.post_vars
if vars.body: if vars.body:
vars.body = vars.body.replace('://%s' % self.host, '://HOSTNAME') vars.body = vars.body.replace('://%s' % self.host, '://HOSTNAME')
@@ -5894,9 +5863,7 @@ class Wiki(object):
return self.not_authorized(page) return self.not_authorized(page)
self.auth.db.wiki_media.id.represent = lambda id, row: \ self.auth.db.wiki_media.id.represent = lambda id, row: \
id if not row.filename else \ id if not row.filename else \
SPAN('@////%i/%s.%s' % SPAN('@////%i/%s.%s' % (id, IS_SLUG.urlify(row.title.split('.')[0]), row.filename.split('.')[-1]))
(id, IS_SLUG.urlify(row.title.split('.')[0]),
row.filename.split('.')[-1]))
self.auth.db.wiki_media.wiki_page.default = page.id self.auth.db.wiki_media.wiki_page.default = page.id
self.auth.db.wiki_media.wiki_page.writable = False self.auth.db.wiki_media.wiki_page.writable = False
links = [] links = []
@@ -6151,6 +6118,7 @@ class Wiki(object):
request.post_vars.render = None request.post_vars.render = None
return render(request.post_vars) return render(request.post_vars)
class Config(object): class Config(object):
def __init__( def __init__(
self, self,
+2
View File
@@ -66,6 +66,7 @@ else:
logger = logging.getLogger("web2py") logger = logging.getLogger("web2py")
def AES_new(key, IV=None): def AES_new(key, IV=None):
""" Returns an AES cipher object and random IV if None specified """ """ Returns an AES cipher object and random IV if None specified """
if IV is None: if IV is None:
@@ -88,6 +89,7 @@ def md5_hash(text):
""" Generates 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'):
""" """
Generates hash with the given text using the specified Generates hash with the given text using the specified
+20 -10
View File
@@ -348,6 +348,7 @@ class IS_LENGTH(Validator):
return (value, translate(self.error_message) return (value, translate(self.error_message)
% dict(min=self.minsize, max=self.maxsize)) % dict(min=self.minsize, max=self.maxsize))
class IS_JSON(Validator): class IS_JSON(Validator):
""" """
Example: Example:
@@ -696,7 +697,7 @@ class IS_NOT_IN_DB(Validator):
def range_error_message(error_message, what_to_enter, minimum, maximum): def range_error_message(error_message, what_to_enter, minimum, maximum):
"build the error message for the number range validators" """build the error message for the number range validators"""
if error_message is None: if error_message is None:
error_message = 'Enter ' + what_to_enter error_message = 'Enter ' + what_to_enter
if minimum is not None and maximum is not None: if minimum is not None and maximum is not None:
@@ -938,7 +939,7 @@ class IS_DECIMAL_IN_RANGE(Validator):
def is_empty(value, empty_regex=None): def is_empty(value, empty_regex=None):
"test empty field" """test empty field"""
if isinstance(value, (str, unicode)): if isinstance(value, (str, unicode)):
value = value.strip() value = value.strip()
if empty_regex is not None and empty_regex.match(value): if empty_regex is not None and empty_regex.match(value):
@@ -1153,6 +1154,7 @@ class IS_EMAIL(Validator):
return (value, None) return (value, None)
return (value, translate(self.error_message)) return (value, translate(self.error_message))
class IS_LIST_OF_EMAILS(object): class IS_LIST_OF_EMAILS(object):
""" """
Example: Example:
@@ -1166,6 +1168,7 @@ class IS_LIST_OF_EMAILS(object):
) )
""" """
split_emails = re.compile('[^,;\s]+') split_emails = re.compile('[^,;\s]+')
def __init__(self, error_message='Invalid emails: %s'): def __init__(self, error_message='Invalid emails: %s'):
self.error_message = error_message self.error_message = error_message
@@ -1334,7 +1337,7 @@ label_split_regex = re.compile(u'[\u002e\u3002\uff0e\uff61]')
def escape_unicode(string): def escape_unicode(string):
''' """
Converts a unicode string into US-ASCII, using a simple conversion scheme. Converts a unicode string into US-ASCII, using a simple conversion scheme.
Each unicode character that does not have a US-ASCII equivalent is Each unicode character that does not have a US-ASCII equivalent is
converted into a URL escaped form based on its hexadecimal value. converted into a URL escaped form based on its hexadecimal value.
@@ -1348,7 +1351,7 @@ def escape_unicode(string):
string: the US-ASCII escaped form of the inputted string string: the US-ASCII escaped form of the inputted string
@author: Jonathan Benn @author: Jonathan Benn
''' """
returnValue = StringIO() returnValue = StringIO()
for character in string: for character in string:
@@ -1363,7 +1366,7 @@ def escape_unicode(string):
def unicode_to_ascii_authority(authority): def unicode_to_ascii_authority(authority):
''' """
Follows the steps in RFC 3490, Section 4 to convert a unicode authority Follows the steps in RFC 3490, Section 4 to convert a unicode authority
string into its ASCII equivalent. string into its ASCII equivalent.
For example, u'www.Alliancefran\xe7aise.nu' will be converted into For example, u'www.Alliancefran\xe7aise.nu' will be converted into
@@ -1382,7 +1385,7 @@ def unicode_to_ascii_authority(authority):
authority authority
@author: Jonathan Benn @author: Jonathan Benn
''' """
# RFC 3490, Section 4, Step 1 # RFC 3490, Section 4, Step 1
# The encodings.idna Python module assumes that AllowUnassigned == True # The encodings.idna Python module assumes that AllowUnassigned == True
@@ -1413,7 +1416,7 @@ def unicode_to_ascii_authority(authority):
def unicode_to_ascii_url(url, prepend_scheme): def unicode_to_ascii_url(url, prepend_scheme):
''' """
Converts the inputed unicode url into a US-ASCII equivalent. This function Converts the inputed unicode url into a US-ASCII equivalent. This function
goes a little beyond RFC 3490, which is limited in scope to the domain name goes a little beyond RFC 3490, which is limited in scope to the domain name
(authority) only. Here, the functionality is expanded to what was observed (authority) only. Here, the functionality is expanded to what was observed
@@ -1443,7 +1446,7 @@ def unicode_to_ascii_url(url, prepend_scheme):
string: a US-ASCII equivalent of the inputed url string: a US-ASCII equivalent of the inputed url
@author: Jonathan Benn @author: Jonathan Benn
''' """
# convert the authority component of the URL into an ASCII punycode string, # convert the authority component of the URL into an ASCII punycode string,
# but encode the rest using the regular URI character encoding # but encode the rest using the regular URI character encoding
@@ -2120,7 +2123,7 @@ class IS_TIME(Validator):
if not value.group('s') is None: if not value.group('s') is None:
s = int(value.group('s')) s = int(value.group('s'))
if value.group('d') == 'pm' and 0 < h < 12: if value.group('d') == 'pm' and 0 < h < 12:
h = h + 12 h += 12
if value.group('d') == 'am' and h == 12: if value.group('d') == 'am' and h == 12:
h = 0 h = 0
if not (h in range(24) and m in range(60) and s if not (h in range(24) and m in range(60) and s
@@ -2134,18 +2137,23 @@ class IS_TIME(Validator):
pass pass
return (ivalue, translate(self.error_message)) return (ivalue, translate(self.error_message))
# A UTC class. # A UTC class.
class UTC(datetime.tzinfo): class UTC(datetime.tzinfo):
"""UTC""" """UTC"""
ZERO = datetime.timedelta(0) ZERO = datetime.timedelta(0)
def utcoffset(self, dt): def utcoffset(self, dt):
return UTC.ZERO return UTC.ZERO
def tzname(self, dt): def tzname(self, dt):
return "UTC" return "UTC"
def dst(self, dt): def dst(self, dt):
return UTC.ZERO return UTC.ZERO
utc = UTC() utc = UTC()
class IS_DATE(Validator): class IS_DATE(Validator):
""" """
Examples: Examples:
@@ -2735,6 +2743,7 @@ class LazyCrypt(object):
def __ne__(self, other): def __ne__(self, other):
return not self.__eq__(other) return not self.__eq__(other)
class CRYPT(object): class CRYPT(object):
""" """
Examples: Examples:
@@ -2852,7 +2861,7 @@ otherset = frozenset(
def calc_entropy(string): def calc_entropy(string):
" calculates 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()
@@ -3374,6 +3383,7 @@ class IS_IPV4(Validator):
return (value, None) return (value, None)
return (value, translate(self.error_message)) return (value, translate(self.error_message))
class IS_IPV6(Validator): class IS_IPV6(Validator):
""" """
Checks if field's value is an IP version 6 address. First attempts to Checks if field's value is an IP version 6 address. First attempts to
+1
View File
@@ -1263,6 +1263,7 @@ end tell
# if the line was not found (under py2exe & when file was modified) # if the line was not found (under py2exe & when file was modified)
import linecache import linecache
py2exe_getline = linecache.getline py2exe_getline = linecache.getline
def getline(filename, lineno, *args, **kwargs): def getline(filename, lineno, *args, **kwargs):
line = py2exe_getline(filename, lineno, *args, **kwargs) line = py2exe_getline(filename, lineno, *args, **kwargs)
if not line: if not line: