Merge branch 'master' of github.com:web2py/web2py
This commit is contained in:
commit
1b39736561
4 files changed
+192
-211
No files matched your search
+128
-160
@@ -287,29 +287,28 @@ 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]',
|
||||||
attachments = None,
|
attachments=None,
|
||||||
cc = None,
|
cc=None,
|
||||||
bcc = None,
|
bcc=None,
|
||||||
reply_to = None,
|
reply_to=None,
|
||||||
sender = None,
|
sender=None,
|
||||||
encoding = 'utf-8',
|
encoding='utf-8',
|
||||||
raw = False,
|
raw=False,
|
||||||
headers = {},
|
headers={},
|
||||||
from_address = None,
|
from_address=None,
|
||||||
cipher_type = None,
|
cipher_type=None,
|
||||||
sign = None,
|
sign=None,
|
||||||
sign_passphrase = None,
|
sign_passphrase=None,
|
||||||
encrypt = None,
|
encrypt=None,
|
||||||
x509_sign_keyfile = None,
|
x509_sign_keyfile=None,
|
||||||
x509_sign_chainfile = None,
|
x509_sign_chainfile=None,
|
||||||
x509_sign_certfile = None,
|
x509_sign_certfile=None,
|
||||||
x509_crypt_certfiles = None,
|
x509_crypt_certfiles=None,
|
||||||
x509_nocerts = None
|
x509_nocerts=None
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Sends an email using data specified in constructor
|
Sends an email using data specified in constructor
|
||||||
@@ -664,7 +663,7 @@ class Mail(object):
|
|||||||
|
|
||||||
# SIGN
|
# SIGN
|
||||||
if sign:
|
if sign:
|
||||||
#key for signing
|
# key for signing
|
||||||
try:
|
try:
|
||||||
keyfile_bio = BIO.openfile(x509_sign_keyfile)\
|
keyfile_bio = BIO.openfile(x509_sign_keyfile)\
|
||||||
if os.path.isfile(x509_sign_keyfile)\
|
if os.path.isfile(x509_sign_keyfile)\
|
||||||
@@ -796,7 +795,7 @@ class Mail(object):
|
|||||||
subject=subject, body=text, **xcc)
|
subject=subject, body=text, **xcc)
|
||||||
else:
|
else:
|
||||||
smtp_args = self.settings.server.split(':')
|
smtp_args = self.settings.server.split(':')
|
||||||
kwargs = dict(timeout = self.settings.timeout)
|
kwargs = dict(timeout=self.settings.timeout)
|
||||||
if self.settings.ssl:
|
if self.settings.ssl:
|
||||||
server = smtplib.SMTP_SSL(*smtp_args, **kwargs)
|
server = smtplib.SMTP_SSL(*smtp_args, **kwargs)
|
||||||
else:
|
else:
|
||||||
@@ -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='',
|
||||||
@@ -849,7 +847,7 @@ class Recaptcha(DIV):
|
|||||||
error_message='invalid',
|
error_message='invalid',
|
||||||
label='Verify:',
|
label='Verify:',
|
||||||
options='',
|
options='',
|
||||||
comment = '',
|
comment='',
|
||||||
ajax=False
|
ajax=False
|
||||||
):
|
):
|
||||||
request = request or current.request
|
request = request or current.request
|
||||||
@@ -942,7 +940,7 @@ class Recaptcha(DIV):
|
|||||||
jQuery.getScript('%(url)s',function() {
|
jQuery.getScript('%(url)s',function() {
|
||||||
Recaptcha.create('%(public_key)s',
|
Recaptcha.create('%(public_key)s',
|
||||||
'recaptcha',jQuery.extend(RecaptchaOptions,{'callback':Recaptcha.focus_response_field}))
|
'recaptcha',jQuery.extend(RecaptchaOptions,{'callback':Recaptcha.focus_response_field}))
|
||||||
}) """ % ({'options':RecaptchaOptions,'url':url_recaptcha_js,'public_key':public_key})
|
}) """ % ({'options': RecaptchaOptions, 'url': url_recaptcha_js, 'public_key': public_key})
|
||||||
captcha = DIV(
|
captcha = DIV(
|
||||||
SCRIPT(
|
SCRIPT(
|
||||||
script,
|
script,
|
||||||
@@ -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":
|
||||||
@@ -1050,14 +1049,14 @@ class Auth(object):
|
|||||||
profile_fields=None,
|
profile_fields=None,
|
||||||
email_case_sensitive=True,
|
email_case_sensitive=True,
|
||||||
username_case_sensitive=True,
|
username_case_sensitive=True,
|
||||||
update_fields = ['email'],
|
update_fields=['email'],
|
||||||
ondelete="CASCADE",
|
ondelete="CASCADE",
|
||||||
client_side = True,
|
client_side=True,
|
||||||
renew_session_onlogin=True,
|
renew_session_onlogin=True,
|
||||||
renew_session_onlogout=True,
|
renew_session_onlogout=True,
|
||||||
keep_session_onlogin=True,
|
keep_session_onlogin=True,
|
||||||
keep_session_onlogout=False,
|
keep_session_onlogout=False,
|
||||||
wiki = Settings(),
|
wiki=Settings(),
|
||||||
)
|
)
|
||||||
# ## these are messages that can be customized
|
# ## these are messages that can be customized
|
||||||
default_messages = dict(
|
default_messages = dict(
|
||||||
@@ -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',
|
||||||
@@ -1263,7 +1261,7 @@ class Auth(object):
|
|||||||
f=f, args=args, vars=vars, scheme=scheme)
|
f=f, args=args, vars=vars, scheme=scheme)
|
||||||
|
|
||||||
def here(self):
|
def here(self):
|
||||||
return URL(args=current.request.args,vars=current.request.get_vars)
|
return URL(args=current.request.args, vars=current.request.get_vars)
|
||||||
|
|
||||||
def __init__(self, environment=None, db=None, mailer=True,
|
def __init__(self, environment=None, db=None, mailer=True,
|
||||||
hmac_key=None, controller='default', function='user',
|
hmac_key=None, controller='default', function='user',
|
||||||
@@ -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")
|
||||||
@@ -1545,10 +1544,10 @@ class Auth(object):
|
|||||||
self.bar[0][3].append((item['name'], False, item['href']))
|
self.bar[0][3].append((item['name'], False, item['href']))
|
||||||
|
|
||||||
def bootstrap3(): # Default web2py scaffolding
|
def bootstrap3(): # Default web2py scaffolding
|
||||||
def rename(icon): return icon+' '+icon.replace('icon','glyphicon')
|
def rename(icon): return icon+' '+icon.replace('icon', 'glyphicon')
|
||||||
self.bar = UL(LI(Anr(I(_class=rename('icon '+items[0]['icon'])),
|
self.bar = UL(LI(Anr(I(_class=rename('icon '+items[0]['icon'])),
|
||||||
' ' + items[0]['name'],
|
' ' + items[0]['name'],
|
||||||
_href=items[0]['href'])),_class='dropdown-menu')
|
_href=items[0]['href'])), _class='dropdown-menu')
|
||||||
del items[0]
|
del items[0]
|
||||||
for item in items:
|
for item in items:
|
||||||
self.bar.insert(-1, LI(Anr(I(_class=rename('icon '+item['icon'])),
|
self.bar.insert(-1, LI(Anr(I(_class=rename('icon '+item['icon'])),
|
||||||
@@ -1557,13 +1556,13 @@ class Auth(object):
|
|||||||
self.bar.insert(-1, LI('', _class='divider'))
|
self.bar.insert(-1, LI('', _class='divider'))
|
||||||
if self.user_id:
|
if self.user_id:
|
||||||
self.bar = LI(Anr(prefix, user_identifier,
|
self.bar = LI(Anr(prefix, user_identifier,
|
||||||
_href='#',_class="dropdown-toggle",
|
_href='#', _class="dropdown-toggle",
|
||||||
data={'toggle':'dropdown'}),
|
data={'toggle': 'dropdown'}),
|
||||||
self.bar,_class='dropdown')
|
self.bar, _class='dropdown')
|
||||||
else:
|
else:
|
||||||
self.bar = LI(Anr(T('Log In'),
|
self.bar = LI(Anr(T('Log In'),
|
||||||
_href='#',_class="dropdown-toggle",
|
_href='#', _class="dropdown-toggle",
|
||||||
data={'toggle':'dropdown'}), self.bar,
|
data={'toggle': 'dropdown'}), self.bar,
|
||||||
_class='dropdown')
|
_class='dropdown')
|
||||||
|
|
||||||
def bare():
|
def bare():
|
||||||
@@ -1714,7 +1713,7 @@ class Auth(object):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
current_record_label = current_record_label or current.T(
|
current_record_label = current_record_label or current.T(
|
||||||
current_record.replace('_',' ').title())
|
current_record.replace('_', ' ').title())
|
||||||
for table in tables:
|
for table in tables:
|
||||||
fieldnames = table.fields()
|
fieldnames = table.fields()
|
||||||
if ('id' in fieldnames and
|
if ('id' in fieldnames and
|
||||||
@@ -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
|
||||||
@@ -2135,16 +2134,15 @@ class Auth(object):
|
|||||||
from gluon.settings import global_settings
|
from gluon.settings import global_settings
|
||||||
if global_settings.web2py_runtime_gae:
|
if global_settings.web2py_runtime_gae:
|
||||||
user = Row(self.table_user()._filter_fields(user, id=True))
|
user = Row(self.table_user()._filter_fields(user, id=True))
|
||||||
delattr(user,'password')
|
delattr(user, 'password')
|
||||||
else:
|
else:
|
||||||
user = Row(user)
|
user = Row(user)
|
||||||
for key, value in user.items():
|
for key, value in user.items():
|
||||||
if callable(value) or key=='password':
|
if callable(value) or key == 'password':
|
||||||
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,
|
||||||
@@ -2424,7 +2414,7 @@ class Auth(object):
|
|||||||
|
|
||||||
if settings.remember_me_form:
|
if settings.remember_me_form:
|
||||||
extra_fields = [
|
extra_fields = [
|
||||||
Field('remember_me','boolean',default=False,
|
Field('remember_me', 'boolean', default=False,
|
||||||
label = self.messages.label_remember_me)]
|
label = self.messages.label_remember_me)]
|
||||||
else:
|
else:
|
||||||
extra_fields = []
|
extra_fields = []
|
||||||
@@ -2549,7 +2539,7 @@ class Auth(object):
|
|||||||
# auth.settings.two_factor_authentication_group
|
# auth.settings.two_factor_authentication_group
|
||||||
if user and self.settings.two_factor_authentication_group:
|
if user and self.settings.two_factor_authentication_group:
|
||||||
role = self.settings.two_factor_authentication_group
|
role = self.settings.two_factor_authentication_group
|
||||||
session.auth_two_factor_enabled = self.has_membership(user_id=user.id,role=role)
|
session.auth_two_factor_enabled = self.has_membership(user_id=user.id, role=role)
|
||||||
# challenge
|
# challenge
|
||||||
if session.auth_two_factor_enabled:
|
if session.auth_two_factor_enabled:
|
||||||
form = SQLFORM.factory(
|
form = SQLFORM.factory(
|
||||||
@@ -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,
|
||||||
@@ -2728,7 +2717,7 @@ class Auth(object):
|
|||||||
if self.settings.register_verify_password:
|
if self.settings.register_verify_password:
|
||||||
extra_fields = [
|
extra_fields = [
|
||||||
Field("password_two", "password", requires=IS_EQUAL_TO(
|
Field("password_two", "password", requires=IS_EQUAL_TO(
|
||||||
request.post_vars.get(passfield,None),
|
request.post_vars.get(passfield, None),
|
||||||
error_message=self.messages.mismatched_password),
|
error_message=self.messages.mismatched_password),
|
||||||
label=current.T("Confirm Password"))]
|
label=current.T("Confirm Password"))]
|
||||||
else:
|
else:
|
||||||
@@ -2772,7 +2761,7 @@ class Auth(object):
|
|||||||
link = self.url(
|
link = self.url(
|
||||||
self.settings.function, args=('verify_email', key), scheme=True)
|
self.settings.function, args=('verify_email', key), scheme=True)
|
||||||
d = dict(form.vars)
|
d = dict(form.vars)
|
||||||
d.update(dict(key=key, link=link,username=form.vars[username]))
|
d.update(dict(key=key, link=link, username=form.vars[username]))
|
||||||
if not (self.settings.mailer and self.settings.mailer.send(
|
if not (self.settings.mailer and self.settings.mailer.send(
|
||||||
to=form.vars.email,
|
to=form.vars.email,
|
||||||
subject=self.messages.verify_email_subject,
|
subject=self.messages.verify_email_subject,
|
||||||
@@ -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,
|
||||||
@@ -3101,7 +3083,7 @@ class Auth(object):
|
|||||||
log = self.messages['reset_password_log']
|
log = self.messages['reset_password_log']
|
||||||
userfield = self.settings.login_userfield or 'username' \
|
userfield = self.settings.login_userfield or 'username' \
|
||||||
if 'username' in table_user.fields else 'email'
|
if 'username' in table_user.fields else 'email'
|
||||||
if userfield=='email':
|
if userfield == 'email':
|
||||||
table_user.email.requires = [
|
table_user.email.requires = [
|
||||||
IS_EMAIL(error_message=self.messages.invalid_email),
|
IS_EMAIL(error_message=self.messages.invalid_email),
|
||||||
IS_IN_DB(self.db, table_user.email,
|
IS_IN_DB(self.db, table_user.email,
|
||||||
@@ -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,
|
||||||
@@ -3211,9 +3191,9 @@ class Auth(object):
|
|||||||
log = self.messages['change_password_log']
|
log = self.messages['change_password_log']
|
||||||
passfield = self.settings.password_field
|
passfield = self.settings.password_field
|
||||||
requires = table_user[passfield].requires
|
requires = table_user[passfield].requires
|
||||||
if not isinstance(requires,(list, tuple)):
|
if not isinstance(requires, (list, tuple)):
|
||||||
requires = [requires]
|
requires = [requires]
|
||||||
requires = filter(lambda t:isinstance(t,CRYPT), requires)
|
requires = filter(lambda t: isinstance(t, CRYPT), requires)
|
||||||
if requires:
|
if requires:
|
||||||
requires[0].min_length = 0
|
requires[0].min_length = 0
|
||||||
form = SQLFORM.factory(
|
form = SQLFORM.factory(
|
||||||
@@ -3237,7 +3217,7 @@ class Auth(object):
|
|||||||
onvalidation=onvalidation,
|
onvalidation=onvalidation,
|
||||||
hideerror=self.settings.hideerror):
|
hideerror=self.settings.hideerror):
|
||||||
|
|
||||||
current_user = s.select(limitby=(0,1), orderby_on_limitby=False).first()
|
current_user = s.select(limitby=(0, 1), orderby_on_limitby=False).first()
|
||||||
if not form.vars['old_password'] == current_user[passfield]:
|
if not form.vars['old_password'] == current_user[passfield]:
|
||||||
form.errors['old_password'] = self.messages.invalid_password
|
form.errors['old_password'] = self.messages.invalid_password
|
||||||
else:
|
else:
|
||||||
@@ -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,
|
||||||
@@ -3314,7 +3293,7 @@ class Auth(object):
|
|||||||
onaccept = self.settings.login_onaccept
|
onaccept = self.settings.login_onaccept
|
||||||
if onaccept:
|
if onaccept:
|
||||||
form = Storage(dict(vars=self.user))
|
form = Storage(dict(vars=self.user))
|
||||||
if not isinstance(onaccept,(list, tuple)):
|
if not isinstance(onaccept, (list, tuple)):
|
||||||
onaccept = [onaccept]
|
onaccept = [onaccept]
|
||||||
for callback in onaccept:
|
for callback in onaccept:
|
||||||
callback(form)
|
callback(form)
|
||||||
@@ -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='',
|
||||||
@@ -3683,7 +3660,7 @@ class Auth(object):
|
|||||||
if group_id == 0:
|
if group_id == 0:
|
||||||
group_id = self.user_group()
|
group_id = self.user_group()
|
||||||
record = self.db(permission.group_id == group_id)(permission.name == name)(permission.table_name == str(table_name))(
|
record = self.db(permission.group_id == group_id)(permission.name == name)(permission.table_name == str(table_name))(
|
||||||
permission.record_id == long(record_id)).select(limitby=(0,1), orderby_on_limitby=False).first()
|
permission.record_id == long(record_id)).select(limitby=(0, 1), orderby_on_limitby=False).first()
|
||||||
if record:
|
if record:
|
||||||
id = record.id
|
id = record.id
|
||||||
else:
|
else:
|
||||||
@@ -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,
|
||||||
@@ -4329,7 +4302,7 @@ class Crud(object):
|
|||||||
"""
|
"""
|
||||||
table = tables[0]
|
table = tables[0]
|
||||||
fields = args.get('fields', table.fields)
|
fields = args.get('fields', table.fields)
|
||||||
validate = args.get('validate',True)
|
validate = args.get('validate', True)
|
||||||
request = current.request
|
request = current.request
|
||||||
db = self.db
|
db = self.db
|
||||||
if not (isinstance(table, Table) or table in db.tables):
|
if not (isinstance(table, Table) or table in db.tables):
|
||||||
@@ -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',
|
||||||
@@ -4886,7 +4856,7 @@ class Service(object):
|
|||||||
if not method in methods:
|
if not method in methods:
|
||||||
return return_error(id, 100, 'method "%s" does not exist' % method)
|
return return_error(id, 100, 'method "%s" does not exist' % method)
|
||||||
try:
|
try:
|
||||||
if isinstance(params,dict):
|
if isinstance(params, dict):
|
||||||
s = methods[method](**params)
|
s = methods[method](**params)
|
||||||
else:
|
else:
|
||||||
s = methods[method](*params)
|
s = methods[method](*params)
|
||||||
@@ -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:
|
||||||
@@ -4986,7 +4954,7 @@ class Service(object):
|
|||||||
if not method in methods:
|
if not method in methods:
|
||||||
return return_error(id, -32601, data='Method "%s" does not exist' % method)
|
return return_error(id, -32601, data='Method "%s" does not exist' % method)
|
||||||
try:
|
try:
|
||||||
if isinstance(params,dict):
|
if isinstance(params, dict):
|
||||||
s = methods[method](**params)
|
s = methods[method](**params)
|
||||||
else:
|
else:
|
||||||
s = methods[method](*params)
|
s = methods[method](*params)
|
||||||
@@ -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
|
||||||
@@ -5407,7 +5374,7 @@ class Expose(object):
|
|||||||
self.filenames = [f[len(path) - 1:] for f in sorted(glob.glob(path))
|
self.filenames = [f[len(path) - 1:] for f in sorted(glob.glob(path))
|
||||||
if not os.path.isdir(f) and not self.isprivate(f)]
|
if not os.path.isdir(f) and not self.isprivate(f)]
|
||||||
if 'README' in self.filenames:
|
if 'README' in self.filenames:
|
||||||
readme = open(os.path.join(filename,'README')).read()
|
readme = open(os.path.join(filename, 'README')).read()
|
||||||
self.paragraph = MARKMIN(readme)
|
self.paragraph = MARKMIN(readme)
|
||||||
else:
|
else:
|
||||||
self.paragraph = None
|
self.paragraph = None
|
||||||
@@ -5464,7 +5431,8 @@ 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,
|
||||||
autolinks=lambda link: expand_one(link, {})).xml()
|
autolinks=lambda link: expand_one(link, {})).xml()
|
||||||
@@ -5576,7 +5544,7 @@ class Wiki(object):
|
|||||||
|
|
||||||
table_definitions = [
|
table_definitions = [
|
||||||
('wiki_page', {
|
('wiki_page', {
|
||||||
'args':[
|
'args': [
|
||||||
Field('slug',
|
Field('slug',
|
||||||
requires=[IS_SLUG(),
|
requires=[IS_SLUG(),
|
||||||
IS_NOT_IN_DB(db, 'wiki_page.slug')],
|
IS_NOT_IN_DB(db, 'wiki_page.slug')],
|
||||||
@@ -5601,20 +5569,20 @@ class Wiki(object):
|
|||||||
requires=IS_EMPTY_OR(
|
requires=IS_EMPTY_OR(
|
||||||
IS_IN_SET(engines))),
|
IS_IN_SET(engines))),
|
||||||
auth.signature],
|
auth.signature],
|
||||||
'vars':{'format':'%(title)s', 'migrate':migrate}}),
|
'vars': {'format': '%(title)s', 'migrate': migrate}}),
|
||||||
('wiki_tag', {
|
('wiki_tag', {
|
||||||
'args':[
|
'args': [
|
||||||
Field('name'),
|
Field('name'),
|
||||||
Field('wiki_page', 'reference wiki_page'),
|
Field('wiki_page', 'reference wiki_page'),
|
||||||
auth.signature],
|
auth.signature],
|
||||||
'vars':{'format':'%(title)s', 'migrate':migrate}}),
|
'vars':{'format': '%(title)s', 'migrate': migrate}}),
|
||||||
('wiki_media', {
|
('wiki_media', {
|
||||||
'args':[
|
'args': [
|
||||||
Field('wiki_page', 'reference wiki_page'),
|
Field('wiki_page', 'reference wiki_page'),
|
||||||
Field('title', required=True),
|
Field('title', required=True),
|
||||||
Field('filename', 'upload', required=True),
|
Field('filename', 'upload', required=True),
|
||||||
auth.signature],
|
auth.signature],
|
||||||
'vars':{'format':'%(title)s', 'migrate':migrate}}),
|
'vars': {'format': '%(title)s', 'migrate': migrate}}),
|
||||||
]
|
]
|
||||||
|
|
||||||
# define only non-existent tables
|
# define only non-existent tables
|
||||||
@@ -5633,7 +5601,7 @@ class Wiki(object):
|
|||||||
|
|
||||||
if self.settings.templates is None and not \
|
if self.settings.templates is None and not \
|
||||||
self.settings.manage_permissions:
|
self.settings.manage_permissions:
|
||||||
self.settings.templates = db.wiki_page.tags.contains('template')&\
|
self.settings.templates = db.wiki_page.tags.contains('template') & \
|
||||||
db.wiki_page.can_read.contains('everybody')
|
db.wiki_page.can_read.contains('everybody')
|
||||||
|
|
||||||
def update_tags_insert(page, id, db=db):
|
def update_tags_insert(page, id, db=db):
|
||||||
@@ -5643,7 +5611,7 @@ class Wiki(object):
|
|||||||
db.wiki_tag.insert(name=tag, wiki_page=id)
|
db.wiki_tag.insert(name=tag, wiki_page=id)
|
||||||
|
|
||||||
def update_tags_update(dbset, page, db=db):
|
def update_tags_update(dbset, page, db=db):
|
||||||
page = dbset.select(limitby=(0,1)).first()
|
page = dbset.select(limitby=(0, 1)).first()
|
||||||
db(db.wiki_tag.wiki_page == page.id).delete()
|
db(db.wiki_tag.wiki_page == page.id).delete()
|
||||||
for tag in page.tags or []:
|
for tag in page.tags or []:
|
||||||
tag = tag.strip().lower()
|
tag = tag.strip().lower()
|
||||||
@@ -5733,7 +5701,7 @@ class Wiki(object):
|
|||||||
elif not zero or not zero.startswith('_'):
|
elif not zero or not zero.startswith('_'):
|
||||||
return self.read(zero)
|
return self.read(zero)
|
||||||
elif zero == '_edit':
|
elif zero == '_edit':
|
||||||
return self.edit(request.args(1) or 'index',request.args(2) or 0)
|
return self.edit(request.args(1) or 'index', request.args(2) or 0)
|
||||||
elif zero == '_editmedia':
|
elif zero == '_editmedia':
|
||||||
return self.editmedia(request.args(1) or 'index')
|
return self.editmedia(request.args(1) or 'index')
|
||||||
elif zero == '_create':
|
elif zero == '_create':
|
||||||
@@ -5804,7 +5772,7 @@ class Wiki(object):
|
|||||||
created_on=page.created_on,
|
created_on=page.created_on,
|
||||||
modified_on=page.modified_on)
|
modified_on=page.modified_on)
|
||||||
|
|
||||||
def edit(self,slug,from_template=0):
|
def edit(self, slug, from_template=0):
|
||||||
auth = self.auth
|
auth = self.auth
|
||||||
db = auth.db
|
db = auth.db
|
||||||
page = db.wiki_page(slug=slug)
|
page = db.wiki_page(slug=slug)
|
||||||
@@ -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')
|
||||||
@@ -5880,9 +5849,9 @@ class Wiki(object):
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
""" % dict(url=URL(args=('_preview', slug)),link_media=('true' if page else 'false'),
|
""" % dict(url=URL(args=('_preview', slug)), link_media=('true' if page else 'false'),
|
||||||
urlmedia=URL(extension='load',
|
urlmedia=URL(extension='load',
|
||||||
args=('_editmedia',slug),
|
args=('_editmedia', slug),
|
||||||
vars=dict(embedded=1)))
|
vars=dict(embedded=1)))
|
||||||
return dict(content=TAG[''](form, SCRIPT(script)))
|
return dict(content=TAG[''](form, SCRIPT(script)))
|
||||||
|
|
||||||
@@ -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 = []
|
||||||
@@ -5907,16 +5874,16 @@ class Wiki(object):
|
|||||||
fragment = self.auth.db.wiki_media.id.represent
|
fragment = self.auth.db.wiki_media.id.represent
|
||||||
csv = False
|
csv = False
|
||||||
create = False
|
create = False
|
||||||
links=[
|
links= [
|
||||||
lambda row:
|
lambda row:
|
||||||
A('copy into source', _href='#', _onclick=script % (fragment(row.id, row)))
|
A('copy into source', _href='#', _onclick=script % (fragment(row.id, row)))
|
||||||
]
|
]
|
||||||
content = SQLFORM.grid(
|
content = SQLFORM.grid(
|
||||||
self.auth.db.wiki_media.wiki_page == page.id,
|
self.auth.db.wiki_media.wiki_page == page.id,
|
||||||
orderby=self.auth.db.wiki_media.title,
|
orderby=self.auth.db.wiki_media.title,
|
||||||
links = links,
|
links=links,
|
||||||
csv = csv,
|
csv=csv,
|
||||||
create = create,
|
create=create,
|
||||||
args=['_editmedia', slug],
|
args=['_editmedia', slug],
|
||||||
user_signature=False)
|
user_signature=False)
|
||||||
return dict(content=content)
|
return dict(content=content)
|
||||||
@@ -5925,12 +5892,12 @@ class Wiki(object):
|
|||||||
if not self.can_edit():
|
if not self.can_edit():
|
||||||
return self.not_authorized()
|
return self.not_authorized()
|
||||||
db = self.auth.db
|
db = self.auth.db
|
||||||
slugs=db(db.wiki_page.id>0).select(db.wiki_page.id,db.wiki_page.slug)
|
slugs = db(db.wiki_page.id > 0).select(db.wiki_page.id, db.wiki_page.slug)
|
||||||
options=[OPTION(row.slug,_value=row.id) for row in slugs]
|
options = [OPTION(row.slug, _value=row.id) for row in slugs]
|
||||||
options.insert(0, OPTION('',_value=''))
|
options.insert(0, OPTION('', _value=''))
|
||||||
fields = [Field("slug", default=current.request.args(1) or
|
fields = [Field("slug", default=current.request.args(1) or
|
||||||
self.settings.force_prefix,
|
self.settings.force_prefix,
|
||||||
requires=(IS_SLUG(), IS_NOT_IN_DB(db,db.wiki_page.slug))),]
|
requires=(IS_SLUG(), IS_NOT_IN_DB(db, db.wiki_page.slug))),]
|
||||||
if self.settings.templates:
|
if self.settings.templates:
|
||||||
fields.append(
|
fields.append(
|
||||||
Field("from_template", "reference wiki_page",
|
Field("from_template", "reference wiki_page",
|
||||||
@@ -5947,7 +5914,7 @@ class Wiki(object):
|
|||||||
if form.process().accepted:
|
if form.process().accepted:
|
||||||
form.vars.from_template = 0 if not form.vars.from_template \
|
form.vars.from_template = 0 if not form.vars.from_template \
|
||||||
else form.vars.from_template
|
else form.vars.from_template
|
||||||
redirect(URL(args=('_edit', form.vars.slug,form.vars.from_template or 0))) # added param
|
redirect(URL(args=('_edit', form.vars.slug, form.vars.from_template or 0))) # added param
|
||||||
return dict(content=form)
|
return dict(content=form)
|
||||||
|
|
||||||
def pages(self):
|
def pages(self):
|
||||||
@@ -5960,14 +5927,14 @@ class Wiki(object):
|
|||||||
wiki_table = self.auth.db.wiki_page
|
wiki_table = self.auth.db.wiki_page
|
||||||
content = SQLFORM.grid(
|
content = SQLFORM.grid(
|
||||||
wiki_table,
|
wiki_table,
|
||||||
fields = [wiki_table.slug,
|
fields=[wiki_table.slug,
|
||||||
wiki_table.title, wiki_table.tags,
|
wiki_table.title, wiki_table.tags,
|
||||||
wiki_table.can_read, wiki_table.can_edit],
|
wiki_table.can_read, wiki_table.can_edit],
|
||||||
links=[
|
links=[
|
||||||
lambda row:
|
lambda row:
|
||||||
A('edit', _href=URL(args=('_edit', row.slug)),_class='btn'),
|
A('edit', _href=URL(args=('_edit', row.slug)), _class='btn'),
|
||||||
lambda row:
|
lambda row:
|
||||||
A('media', _href=URL(args=('_editmedia', row.slug)),_class='btn')],
|
A('media', _href=URL(args=('_editmedia', row.slug)), _class='btn')],
|
||||||
details=False, editable=False, deletable=False, create=False,
|
details=False, editable=False, deletable=False, create=False,
|
||||||
orderby=self.auth.db.wiki_page.title,
|
orderby=self.auth.db.wiki_page.title,
|
||||||
args=['_pages'],
|
args=['_pages'],
|
||||||
@@ -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,
|
||||||
@@ -6166,7 +6134,7 @@ class Config(object):
|
|||||||
self.filename = filename
|
self.filename = filename
|
||||||
|
|
||||||
def read(self):
|
def read(self):
|
||||||
if not( isinstance(current.session['settings_%s' % self.section], dict) ):
|
if not(isinstance(current.session['settings_%s' % self.section], dict)):
|
||||||
settings = dict(self.config.items(self.section))
|
settings = dict(self.config.items(self.section))
|
||||||
else:
|
else:
|
||||||
settings = current.session['settings_%s' % self.section]
|
settings = current.session['settings_%s' % self.section]
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
+49
-39
@@ -190,9 +190,9 @@ class IS_MATCH(Validator):
|
|||||||
if not expression.endswith('$'):
|
if not expression.endswith('$'):
|
||||||
expression = '(%s)$' % expression
|
expression = '(%s)$' % expression
|
||||||
if is_unicode:
|
if is_unicode:
|
||||||
if not isinstance(expression,unicode):
|
if not isinstance(expression, unicode):
|
||||||
expression = expression.decode('utf8')
|
expression = expression.decode('utf8')
|
||||||
self.regex = re.compile(expression,re.UNICODE)
|
self.regex = re.compile(expression, re.UNICODE)
|
||||||
else:
|
else:
|
||||||
self.regex = re.compile(expression)
|
self.regex = re.compile(expression)
|
||||||
self.error_message = error_message
|
self.error_message = error_message
|
||||||
@@ -200,7 +200,7 @@ class IS_MATCH(Validator):
|
|||||||
self.is_unicode = is_unicode
|
self.is_unicode = is_unicode
|
||||||
|
|
||||||
def __call__(self, value):
|
def __call__(self, value):
|
||||||
if self.is_unicode and not isinstance(value,unicode):
|
if self.is_unicode and not isinstance(value, unicode):
|
||||||
match = self.regex.search(str(value).decode('utf8'))
|
match = self.regex.search(str(value).decode('utf8'))
|
||||||
else:
|
else:
|
||||||
match = self.regex.search(str(value))
|
match = self.regex.search(str(value))
|
||||||
@@ -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:
|
||||||
@@ -377,7 +378,7 @@ class IS_JSON(Validator):
|
|||||||
except JSONErrors:
|
except JSONErrors:
|
||||||
return (value, translate(self.error_message))
|
return (value, translate(self.error_message))
|
||||||
|
|
||||||
def formatter(self,value):
|
def formatter(self, value):
|
||||||
if value is None:
|
if value is None:
|
||||||
return None
|
return None
|
||||||
if self.native_json:
|
if self.native_json:
|
||||||
@@ -669,7 +670,7 @@ class IS_NOT_IN_DB(Validator):
|
|||||||
self.record_id = id
|
self.record_id = id
|
||||||
|
|
||||||
def __call__(self, value):
|
def __call__(self, value):
|
||||||
if isinstance(value,unicode):
|
if isinstance(value, unicode):
|
||||||
value = value.encode('utf8')
|
value = value.encode('utf8')
|
||||||
else:
|
else:
|
||||||
value = str(value)
|
value = str(value)
|
||||||
@@ -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,7 +1168,8 @@ 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
|
||||||
|
|
||||||
def __call__(self, value):
|
def __call__(self, value):
|
||||||
@@ -1182,7 +1185,7 @@ class IS_LIST_OF_EMAILS(object):
|
|||||||
return (value,
|
return (value,
|
||||||
translate(self.error_message) % ', '.join(bad_emails))
|
translate(self.error_message) % ', '.join(bad_emails))
|
||||||
|
|
||||||
def formatter(self,value,row=None):
|
def formatter(self, value, row=None):
|
||||||
return ', '.join(value or [])
|
return ', '.join(value or [])
|
||||||
|
|
||||||
|
|
||||||
@@ -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,19 +1385,19 @@ 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
|
||||||
|
|
||||||
#RFC 3490, Section 4, Step 2
|
# RFC 3490, Section 4, Step 2
|
||||||
labels = label_split_regex.split(authority)
|
labels = label_split_regex.split(authority)
|
||||||
|
|
||||||
#RFC 3490, Section 4, Step 3
|
# RFC 3490, Section 4, Step 3
|
||||||
#The encodings.idna Python module assumes that UseSTD3ASCIIRules == False
|
# The encodings.idna Python module assumes that UseSTD3ASCIIRules == False
|
||||||
|
|
||||||
#RFC 3490, Section 4, Step 4
|
# RFC 3490, Section 4, Step 4
|
||||||
#We use the ToASCII operation because we are about to put the authority
|
# We use the ToASCII operation because we are about to put the authority
|
||||||
#into an IDN-unaware slot
|
# into an IDN-unaware slot
|
||||||
asciiLabels = []
|
asciiLabels = []
|
||||||
try:
|
try:
|
||||||
import encodings.idna
|
import encodings.idna
|
||||||
@@ -1402,18 +1405,18 @@ def unicode_to_ascii_authority(authority):
|
|||||||
if label:
|
if label:
|
||||||
asciiLabels.append(encodings.idna.ToASCII(label))
|
asciiLabels.append(encodings.idna.ToASCII(label))
|
||||||
else:
|
else:
|
||||||
#encodings.idna.ToASCII does not accept an empty string, but
|
# encodings.idna.ToASCII does not accept an empty string, but
|
||||||
#it is necessary for us to allow for empty labels so that we
|
# it is necessary for us to allow for empty labels so that we
|
||||||
#don't modify the URL
|
# don't modify the URL
|
||||||
asciiLabels.append('')
|
asciiLabels.append('')
|
||||||
except:
|
except:
|
||||||
asciiLabels = [str(label) for label in labels]
|
asciiLabels = [str(label) for label in labels]
|
||||||
#RFC 3490, Section 4, Step 5
|
# RFC 3490, Section 4, Step 5
|
||||||
return str(reduce(lambda x, y: x + unichr(0x002E) + y, asciiLabels))
|
return str(reduce(lambda x, y: x + unichr(0x002E) + y, asciiLabels))
|
||||||
|
|
||||||
|
|
||||||
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,23 +1446,23 @@ 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
|
||||||
|
|
||||||
groups = url_split_regex.match(url).groups()
|
groups = url_split_regex.match(url).groups()
|
||||||
#If no authority was found
|
# If no authority was found
|
||||||
if not groups[3]:
|
if not groups[3]:
|
||||||
#Try appending a scheme to see if that fixes the problem
|
# Try appending a scheme to see if that fixes the problem
|
||||||
scheme_to_prepend = prepend_scheme or 'http'
|
scheme_to_prepend = prepend_scheme or 'http'
|
||||||
groups = url_split_regex.match(
|
groups = url_split_regex.match(
|
||||||
unicode(scheme_to_prepend) + u'://' + url).groups()
|
unicode(scheme_to_prepend) + u'://' + url).groups()
|
||||||
#if we still can't find the authority
|
# if we still can't find the authority
|
||||||
if not groups[3]:
|
if not groups[3]:
|
||||||
raise Exception('No authority component found, ' +
|
raise Exception('No authority component found, ' +
|
||||||
'could not decode unicode to US-ASCII')
|
'could not decode unicode to US-ASCII')
|
||||||
|
|
||||||
#We're here if we found an authority, let's rebuild the URL
|
# We're here if we found an authority, let's rebuild the URL
|
||||||
scheme = groups[1]
|
scheme = groups[1]
|
||||||
authority = groups[3]
|
authority = groups[3]
|
||||||
path = groups[4] or ''
|
path = groups[4] or ''
|
||||||
@@ -2047,12 +2050,12 @@ class IS_URL(Validator):
|
|||||||
try:
|
try:
|
||||||
asciiValue = unicode_to_ascii_url(value, self.prepend_scheme)
|
asciiValue = unicode_to_ascii_url(value, self.prepend_scheme)
|
||||||
except Exception:
|
except Exception:
|
||||||
#If we are not able to convert the unicode url into a
|
# If we are not able to convert the unicode url into a
|
||||||
# US-ASCII URL, then the URL is not valid
|
# US-ASCII URL, then the URL is not valid
|
||||||
return (value, translate(self.error_message))
|
return (value, translate(self.error_message))
|
||||||
|
|
||||||
methodResult = subMethod(asciiValue)
|
methodResult = subMethod(asciiValue)
|
||||||
#if the validation of the US-ASCII version of the value failed
|
# if the validation of the US-ASCII version of the value failed
|
||||||
if not methodResult[1] is None:
|
if not methodResult[1] is None:
|
||||||
# then return the original input value, not the US-ASCII version
|
# then return the original input value, not the US-ASCII version
|
||||||
return (value, methodResult[1])
|
return (value, methodResult[1])
|
||||||
@@ -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:
|
||||||
@@ -2159,7 +2167,7 @@ class IS_DATE(Validator):
|
|||||||
|
|
||||||
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):
|
||||||
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
|
||||||
@@ -2402,7 +2410,7 @@ class IS_LIST_OF(Validator):
|
|||||||
new_value = []
|
new_value = []
|
||||||
other = self.other
|
other = self.other
|
||||||
if self.other:
|
if self.other:
|
||||||
if not isinstance(other, (list,tuple)):
|
if not isinstance(other, (list, tuple)):
|
||||||
other = [other]
|
other = [other]
|
||||||
for item in ivalue:
|
for item in ivalue:
|
||||||
v = item
|
v = item
|
||||||
@@ -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
|
||||||
|
|||||||
+13
-12
@@ -143,7 +143,7 @@ class web2pyDialog(object):
|
|||||||
root.withdraw()
|
root.withdraw()
|
||||||
|
|
||||||
self.root = Tkinter.Toplevel(root, bg=bg_color)
|
self.root = Tkinter.Toplevel(root, bg=bg_color)
|
||||||
self.root.resizable(0,0)
|
self.root.resizable(0, 0)
|
||||||
self.root.title(ProgramName)
|
self.root.title(ProgramName)
|
||||||
|
|
||||||
self.options = options
|
self.options = options
|
||||||
@@ -151,7 +151,7 @@ class web2pyDialog(object):
|
|||||||
self.menu = Tkinter.Menu(self.root)
|
self.menu = Tkinter.Menu(self.root)
|
||||||
servermenu = Tkinter.Menu(self.menu, tearoff=0)
|
servermenu = Tkinter.Menu(self.menu, tearoff=0)
|
||||||
httplog = os.path.join(self.options.folder, 'httpserver.log')
|
httplog = os.path.join(self.options.folder, 'httpserver.log')
|
||||||
iconphoto = os.path.join('extras','icons','web2py.gif')
|
iconphoto = os.path.join('extras', 'icons', 'web2py.gif')
|
||||||
if os.path.exists(iconphoto):
|
if os.path.exists(iconphoto):
|
||||||
img = Tkinter.PhotoImage(file=iconphoto)
|
img = Tkinter.PhotoImage(file=iconphoto)
|
||||||
self.root.tk.call('wm', 'iconphoto', self.root._w, img)
|
self.root.tk.call('wm', 'iconphoto', self.root._w, img)
|
||||||
@@ -206,7 +206,7 @@ class web2pyDialog(object):
|
|||||||
self.logoarea.grid(row=0, column=0, columnspan=4, sticky=sticky)
|
self.logoarea.grid(row=0, column=0, columnspan=4, sticky=sticky)
|
||||||
self.logoarea.after(1000, self.update_canvas)
|
self.logoarea.after(1000, self.update_canvas)
|
||||||
|
|
||||||
logo = os.path.join('extras','icons','splashlogo.gif')
|
logo = os.path.join('extras', 'icons', 'splashlogo.gif')
|
||||||
if os.path.exists(logo):
|
if os.path.exists(logo):
|
||||||
img = Tkinter.PhotoImage(file=logo)
|
img = Tkinter.PhotoImage(file=logo)
|
||||||
pnl = Tkinter.Label(self.logoarea, image=img, background=bg_color, bd=0)
|
pnl = Tkinter.Label(self.logoarea, image=img, background=bg_color, bd=0)
|
||||||
@@ -328,7 +328,7 @@ class web2pyDialog(object):
|
|||||||
if os.path.exists(
|
if os.path.exists(
|
||||||
'applications/%s/models/scheduler.py' % arq)]
|
'applications/%s/models/scheduler.py' % arq)]
|
||||||
if start:
|
if start:
|
||||||
#the widget takes care of starting the scheduler
|
# the widget takes care of starting the scheduler
|
||||||
if self.options.scheduler and self.options.with_scheduler:
|
if self.options.scheduler and self.options.with_scheduler:
|
||||||
apps = [app.strip() for app
|
apps = [app.strip() for app
|
||||||
in self.options.scheduler.split(',')
|
in self.options.scheduler.split(',')
|
||||||
@@ -336,7 +336,7 @@ class web2pyDialog(object):
|
|||||||
for app in apps:
|
for app in apps:
|
||||||
self.try_start_scheduler(app)
|
self.try_start_scheduler(app)
|
||||||
|
|
||||||
#reset the menu
|
# reset the menu
|
||||||
self.schedmenu.delete(0, len(available_apps))
|
self.schedmenu.delete(0, len(available_apps))
|
||||||
for arq in available_apps:
|
for arq in available_apps:
|
||||||
if arq not in self.scheduler_processes:
|
if arq not in self.scheduler_processes:
|
||||||
@@ -413,7 +413,7 @@ class web2pyDialog(object):
|
|||||||
|
|
||||||
def connect_pages(self):
|
def connect_pages(self):
|
||||||
""" Connects 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(
|
||||||
'applications/%s/__init__.py' % arq)]
|
'applications/%s/__init__.py' % arq)]
|
||||||
@@ -939,13 +939,13 @@ def console():
|
|||||||
if options.gae:
|
if options.gae:
|
||||||
if not os.path.exists('app.yaml'):
|
if not os.path.exists('app.yaml'):
|
||||||
name = raw_input("Your GAE app name: ")
|
name = raw_input("Your GAE app name: ")
|
||||||
content = open(os.path.join('examples','app.example.yaml'),'rb').read()
|
content = open(os.path.join('examples', 'app.example.yaml'), 'rb').read()
|
||||||
open('app.yaml','wb').write(content.replace("yourappname",name))
|
open('app.yaml', 'wb').write(content.replace("yourappname", name))
|
||||||
else:
|
else:
|
||||||
print "app.yaml alreday exists in the web2py folder"
|
print "app.yaml alreday exists in the web2py folder"
|
||||||
if not os.path.exists('gaehandler.py'):
|
if not os.path.exists('gaehandler.py'):
|
||||||
content = open(os.path.join('handlers','gaehandler.py'),'rb').read()
|
content = open(os.path.join('handlers', 'gaehandler.py'), 'rb').read()
|
||||||
open('gaehandler.py','wb').write(content)
|
open('gaehandler.py', 'wb').write(content)
|
||||||
else:
|
else:
|
||||||
print "gaehandler.py alreday exists in the web2py folder"
|
print "gaehandler.py alreday exists in the web2py folder"
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
@@ -1112,7 +1112,7 @@ def start(cron=True):
|
|||||||
if hasattr(options, key):
|
if hasattr(options, key):
|
||||||
setattr(options, key, getattr(options2, key))
|
setattr(options, key, getattr(options2, key))
|
||||||
|
|
||||||
logfile0 = os.path.join('extras','examples','logging.example.conf')
|
logfile0 = os.path.join('extras', 'examples', 'logging.example.conf')
|
||||||
if not os.path.exists('logging.conf') and os.path.exists(logfile0):
|
if not os.path.exists('logging.conf') and os.path.exists(logfile0):
|
||||||
import shutil
|
import shutil
|
||||||
sys.stdout.write("Copying logging.conf.example to logging.conf ... ")
|
sys.stdout.write("Copying logging.conf.example to logging.conf ... ")
|
||||||
@@ -1183,7 +1183,7 @@ def start(cron=True):
|
|||||||
|
|
||||||
root = None
|
root = None
|
||||||
|
|
||||||
if not options.nogui and options.password=='<ask>':
|
if not options.nogui and options.password == '<ask>':
|
||||||
try:
|
try:
|
||||||
import Tkinter
|
import Tkinter
|
||||||
havetk = True
|
havetk = True
|
||||||
@@ -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:
|
||||||
|
|||||||
Reference in new issue
Block a user